📄 madplay.c
字号:
/* * NAME: get_decibels() * DESCRIPTION: parse a decibel value into a linear ratio or die */staticdouble get_decibels(char const *str){ double db; if (parse_decibels(&db, str) == -1) die(_("invalid decibel specification \"%s\""), str); if (db < DB_MIN || db > DB_MAX) die(_("decibel value must be in the range %+d to %+d dB"), DB_MIN, DB_MAX); return db;}/* * NAME: parse_hertz() * DESCRIPTION: parse a hertz specification string */staticint parse_hertz(double *hz, char const *str){ *hz = strtod(str, (char **) &str); while (isspace((unsigned char) *str)) ++str; if (*str == 'k' || *str == 'K') { *hz *= 1000; do ++str; while (isspace((unsigned char) *str)); } if (strncasecmp(str, "Hz", 2) == 0) { str += 2; while (isspace((unsigned char) *str)) ++str; } if (*str != 0) return -1; return 0;}/* * NAME: get_hertz() * DESCRIPTION: parse a hertz value or die */staticunsigned int get_hertz(char const *str){ double hz; enum { HZ_MIN = 1000, HZ_MAX = 0xffff }; if (parse_hertz(&hz, str) == -1) die(_("invalid hertz specification \"%s\""), str); if (hz < HZ_MIN || hz > HZ_MAX) die(_("hertz value must be in the range %u to %u Hz"), HZ_MIN, HZ_MAX); return (unsigned int) (hz + 0.5);}/* * NAME: get_options() * DESCRIPTION: parse command-line options or die */staticvoid get_options(int argc, char *argv[], struct player *player){ int opt, index; int ttyset = 0, preamp = 0; while ((opt = getopt_long(argc, argv, "vqQ" /* verbosity options */ "i" /* decoding options */ "o:b:R:da:A:G::" /* audio output options */# if 0 "g:x"# endif "12mS" /* channel selection options */ "s:t:zr::" /* playback options */ "TVh", /* miscellaneous options */ options, &index)) != -1) { switch (opt) { case 0: break; case '1': case '2': player->output.select = PLAYER_CHANNEL_LEFT + (opt - '1'); break; case 'a': player->output.attamp_db = get_decibels(optarg); preamp = 1; break; case 'A': player->output.voladj_db = get_decibels(optarg); player->options |= PLAYER_OPTION_IGNOREVOLADJ; break; case -'a': if (player->ancillary.path) die(_("multiple output destinations not supported")); player->ancillary.path = optarg; break; case 'b': opt = atoi(optarg); if (opt <= 0) die(_("invalid bit depth \"%s\""), optarg); player->output.precision_in = opt; break;# if defined(USE_TTY) case -'c': player->options |= PLAYER_OPTION_TTYCONTROL; ttyset = 1; break; case -'C': player->options &= ~PLAYER_OPTION_TTYCONTROL; ttyset = 1; break;# endif case 'd': player->output.mode = AUDIO_MODE_ROUND; break; case -'d': player->options |= PLAYER_OPTION_DOWNSAMPLE; break;# if 0 case 'g': player->gap = get_time(optarg, 0, _("gap time")); player->options |= PLAYER_OPTION_GAP; break;# endif case 'G': player->output.replay_gain |= PLAYER_RGAIN_ENABLED; if (optarg) { size_t len; len = strlen(optarg); if (len && strncmp(optarg, "audiophile", len) == 0) player->output.replay_gain |= PLAYER_RGAIN_AUDIOPHILE; else if (len && strncmp(optarg, "radio", len) == 0) ; else die(_("invalid Replay Gain argument \"%s\""), optarg); } if (!preamp) player->output.attamp_db = +6; /* default pre-amp */ break; case 'h': show_usage(1); exit(0); case 'i': player->options |= PLAYER_OPTION_IGNORECRC; break; case -'i': player->fade_in = get_time(optarg ? optarg : FADE_DEFAULT, 1, _("fade-in time")); player->options |= PLAYER_OPTION_FADEIN; break; case -'l': ver_license(stdout); exit(0); case 'm': player->output.select = PLAYER_CHANNEL_MONO; break; case 'o': if (player->output.path) die(_("multiple output destinations not supported")); player->output.path = optarg; player->output.command = audio_output(&player->output.path); if (player->output.command == 0) die(_("unknown output format type for \"%s\""), optarg); if (!ttyset) player->options &= ~PLAYER_OPTION_TTYCONTROL; break;# if 0 case -'o': player->fade_out = get_time(optarg ? optarg : FADE_DEFAULT, 1, _("fade-out time")); player->options |= PLAYER_OPTION_FADEOUT; break;# endif case 'q': player->verbosity = -1; if (!ttyset) player->options &= ~PLAYER_OPTION_TTYCONTROL; break; case 'Q': player->verbosity = -2; if (!ttyset) player->options &= ~PLAYER_OPTION_TTYCONTROL; break; case 'r': if (optarg == 0) player->repeat = -1; else { player->repeat = atoi(optarg); if (player->repeat <= 0) die(_("invalid repeat count \"%s\""), optarg); } break; case 'R': player->output.speed_request = get_hertz(optarg); break; case 's': player->global_start = get_time(optarg, 0, _("start time")); player->options |= PLAYER_OPTION_SKIP; break; case 'S': player->output.select = PLAYER_CHANNEL_STEREO; break; case 't': player->global_stop = get_time(optarg, 1, _("playing time")); player->options |= PLAYER_OPTION_TIMED; break; case -'t': { size_t len; len = strlen(optarg); if (len && strncmp(optarg, "remaining", len) == 0) player->stats.show = STATS_SHOW_REMAINING; else if (len && strncmp(optarg, "current", len) == 0) player->stats.show = STATS_SHOW_CURRENT; else if (len && strncmp(optarg, "overall", len) == 0) player->stats.show = STATS_SHOW_OVERALL; else die(_("invalid display time argument \"%s\""), optarg); } break; case 'T': player->options |= PLAYER_OPTION_SHOWTAGSONLY; break; case 'v': player->verbosity = +1; break; case 'V': ver_version(stdout); fprintf(stderr, "`%s --license' %s.\n", argv0, _("for license and warranty information")); exit(0);# if 0 case 'x': player->options |= PLAYER_OPTION_CROSSFADE; break;# endif case 'z': player->options |= PLAYER_OPTION_SHUFFLE; break; case '?': show_usage(0); exit(1); default: assert(!"option handler"); } } if (optind == argc) { show_usage(0); exit(2); }}/* * NAME: main() * DESCRIPTION: program entry point */int main(int argc, char *argv[]){ struct player player; int result = 0; argv0 = argv[0]; /* ensure binary standard I/O */# if defined(_WIN32) _setmode(_fileno(stdin), _O_BINARY); _setmode(_fileno(stdout), _O_BINARY);# endif /* internationalization support */# if defined(ENABLE_NLS) setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE);# endif /* initialize and get options */ player_init(&player);# if !defined(__CYGWIN__) /* Cygwin support for this is currently buggy */ /* check for default tty control */ if (isatty(STDIN_FILENO)) player.options |= PLAYER_OPTION_TTYCONTROL;# endif get_options(argc, argv, &player); /* main processing */ if (player.verbosity >= 0) ver_banner(stderr); if (player.options & PLAYER_OPTION_CROSSFADE) { if (!(player.options & PLAYER_OPTION_GAP)) warn(_("cross-fade ignored without gap")); else if (mad_timer_sign(player.gap) >= 0) warn(_("cross-fade ignored without negative gap")); } if (player.output.replay_gain & PLAYER_RGAIN_ENABLED) { if (player.options & PLAYER_OPTION_IGNOREVOLADJ) warn(_("volume adjustment ignored with Replay Gain enabled")); else player.options |= PLAYER_OPTION_IGNOREVOLADJ; } if ((player.options & PLAYER_OPTION_SHOWTAGSONLY) && player.repeat != 1) { warn(_("ignoring repeat")); player.repeat = 1; } /* make stop time absolute */ if (player.options & PLAYER_OPTION_TIMED) mad_timer_add(&player.global_stop, player.global_start); /* get default audio output module */ if (player.output.command == 0 && !(player.options & PLAYER_OPTION_SHOWTAGSONLY)) player.output.command = audio_output(0);# if defined(EXPERIMENTAL) if (external_mix) { player.options |= PLAYER_OPTION_EXTERNALMIX; player.output.command = 0; } if (experimental) player.options |= PLAYER_OPTION_EXPERIMENTAL;# endif /* run the player */ if (player_run(&player, argc - optind, (char const **) &argv[optind]) == -1) result = 4; /* finish up */ player_finish(&player); return result;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -