void dspio_done(void *dspio) { pcm_done(); midi_done(); rng_destroy(&DSPIO->fifo_in); rng_destroy(&DSPIO->fifo_out); rng_destroy(&DSPIO->midi_fifo_in); rng_destroy(&DSPIO->midi_fifo_out); free(dspio); }
int main(int argc, char **argv) { int c, background, unit; int pmin, pmax, rmin, rmax; char base[PATH_MAX], path[PATH_MAX]; unsigned int mode, dup, mmc, vol; unsigned int hold, autovol, bufsz, round, rate; const char *str; struct aparams par; struct dev *d; struct port *p; struct listen *l; atexit(log_flush); /* * global options defaults */ vol = 118; dup = 1; mmc = 0; hold = 0; autovol = 1; bufsz = 0; round = 0; rate = DEFAULT_RATE; unit = 0; background = 1; pmin = 0; pmax = 1; rmin = 0; rmax = 1; aparams_init(&par); mode = MODE_PLAY | MODE_REC; setsig(); filelist_init(); while ((c = getopt(argc, argv, "a:b:c:C:de:f:j:L:m:Mq:r:s:t:U:v:w:x:z:")) != -1) { switch (c) { case 'd': log_level++; background = 0; break; case 'U': if (listen_list) errx(1, "-U must come before -L"); unit = strtonum(optarg, 0, 15, &str); if (str) errx(1, "%s: unit number is %s", optarg, str); break; case 'L': listen_new_tcp(optarg, AUCAT_PORT + unit); break; case 'm': mode = opt_mode(); break; case 'j': dup = opt_onoff(); break; case 't': mmc = opt_mmc(); break; case 'c': opt_ch(&pmin, &pmax); break; case 'C': opt_ch(&rmin, &rmax); break; case 'e': opt_enc(&par); break; case 'r': rate = strtonum(optarg, RATE_MIN, RATE_MAX, &str); if (str) errx(1, "%s: rate is %s", optarg, str); break; case 'v': vol = strtonum(optarg, 0, MIDI_MAXCTL, &str); if (str) errx(1, "%s: volume is %s", optarg, str); break; case 's': if ((d = dev_list) == NULL) { d = mkdev(DEFAULT_DEV, &par, 0, bufsz, round, rate, hold, autovol); } mkopt(optarg, d, pmin, pmax, rmin, rmax, mode, vol, mmc, dup); break; case 'q': p = port_new(optarg, MODE_MIDIMASK, hold); if (!p) errx(1, "%s: can't open port", optarg); break; case 'a': hold = opt_onoff(); break; case 'w': autovol = opt_onoff(); break; case 'b': bufsz = strtonum(optarg, 1, RATE_MAX, &str); if (str) errx(1, "%s: buffer size is %s", optarg, str); break; case 'z': round = strtonum(optarg, 1, SHRT_MAX, &str); if (str) errx(1, "%s: block size is %s", optarg, str); break; case 'f': mkdev(optarg, &par, 0, bufsz, round, rate, hold, autovol); break; case 'M': /* XXX: for compatibility with aucat, remove this */ break; default: fputs(usagestr, stderr); return 1; } } argc -= optind; argv += optind; if (argc > 0) { fputs(usagestr, stderr); return 1; } if (dev_list == NULL) mkdev(DEFAULT_DEV, &par, 0, bufsz, round, rate, hold, autovol); for (d = dev_list; d != NULL; d = d->next) { if (opt_byname("default", d->num)) continue; mkopt("default", d, pmin, pmax, rmin, rmax, mode, vol, mmc, dup); } getbasepath(base, sizeof(base)); snprintf(path, PATH_MAX, "%s/%s%u", base, AUCAT_PATH, unit); listen_new_un(path); if (geteuid() == 0) privdrop(); midi_init(); for (p = port_list; p != NULL; p = p->next) { if (!port_init(p)) return 1; } for (d = dev_list; d != NULL; d = d->next) { if (!dev_init(d)) return 1; } for (l = listen_list; l != NULL; l = l->next) { if (!listen_init(l)) return 1; } if (background) { log_flush(); log_level = 0; if (daemon(0, 0) < 0) err(1, "daemon"); } /* * Loop, start audio. */ for (;;) { if (quit_flag) break; if (!file_poll()) break; } while (listen_list != NULL) listen_close(listen_list); while (sock_list != NULL) sock_close(sock_list); while (opt_list != NULL) opt_del(opt_list); for (d = dev_list; d != NULL; d = d->next) dev_done(d); for (p = port_list; p != NULL; p = p->next) port_done(p); midi_done(); while (file_poll()) ; /* nothing */ while (dev_list) dev_del(dev_list); while (port_list) port_del(port_list); filelist_done(); rmdir(base); unsetsig(); return 0; }