[xmp] Add option for vblank-based timing

Use the --vblank command-line option to force vblank-based timing instead
of CIA tempo setting. Needed by some modules such as Klisje paa klisje.
Needs new timing API.

Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
master
Claudio Matsuoka 13 years ago
parent 47b8e2d93f
commit cf788f338f
  1. 3
      src/common.h
  2. 111
      src/main.c
  3. 10
      src/options.c
  4. 3
      src/xmp.1

@ -15,7 +15,8 @@ struct options {
int loop; /* loop module */
int random; /* play in random order */
int reverse; /* reverse stereo channels */
int verbose;
int vblank; /* use vblank timing */
int verbose; /* verbosity level */
int silent; /* silent output */
int info; /* display information and exit */
int probeonly; /* probe sound driver and exit */

@ -147,7 +147,7 @@ int main(int argc, char **argv)
xmp_context handle;
struct xmp_module_info mi;
struct xmp_frame_info fi;
struct options options;
struct options opt;
struct control control;
int i;
int first;
@ -166,46 +166,46 @@ int main(int argc, char **argv)
init_sound_drivers();
memset(&options, 0, sizeof (struct options));
memset(&opt, 0, sizeof (struct options));
memset(&control, 0, sizeof (struct control));
/* set defaults */
options.verbose = 1;
options.rate = 44100;
options.mix = -1;
options.driver_id = NULL;
options.interp = XMP_INTERP_SPLINE;
options.dsp = XMP_DSP_LOWPASS;
opt.verbose = 1;
opt.rate = 44100;
opt.mix = -1;
opt.driver_id = NULL;
opt.interp = XMP_INTERP_SPLINE;
opt.dsp = XMP_DSP_LOWPASS;
/* read configuration file */
read_config(&options);
read_config(&opt);
get_options(argc, argv, &options);
get_options(argc, argv, &opt);
if (!options.probeonly && optind >= argc) {
if (!opt.probeonly && optind >= argc) {
fprintf(stderr, "%s: no modules to play\n"
"Use `%s --help' for more information.\n",
argv[0], argv[0]);
exit(EXIT_FAILURE);
}
if (options.interp < 0) {
if (opt.interp < 0) {
fprintf(stderr, "%s: unknown interpolation type\n"
"Use `%s --help' for more information.\n",
argv[0], argv[0]);
exit(EXIT_FAILURE);
}
if (options.silent) {
options.driver_id = "null";
if (opt.silent) {
opt.driver_id = "null";
}
sound = select_sound_driver(&options);
sound = select_sound_driver(&opt);
if (sound == NULL) {
fprintf(stderr, "%s: can't initialize sound", argv[0]);
if (options.driver_id != NULL) {
fprintf(stderr, " (driver = %s)", options.driver_id);
if (opt.driver_id != NULL) {
fprintf(stderr, " (driver = %s)", opt.driver_id);
}
fprintf(stderr, "\n");
@ -215,25 +215,25 @@ int main(int argc, char **argv)
exit(EXIT_FAILURE);
}
if (options.verbose > 0) {
if (opt.verbose > 0) {
report("Extended Module Player " VERSION "\n"
"Copyright (C) 1996-2012 Claudio Matsuoka and Hipolito Carraro Jr\n");
report("Using %s\n", sound->description);
report("Mixer set to %d Hz, %dbit, %s%s%s\n", options.rate,
options.format & XMP_FORMAT_8BIT ? 8 : 16,
options.interp == XMP_INTERP_LINEAR ? "linear interpolated " :
options.interp == XMP_INTERP_SPLINE ? "cubic spline interpolated " : "",
options.format & XMP_FORMAT_MONO ? "mono" : "stereo",
options.dsp & XMP_DSP_LOWPASS ? "" : " (no filter)");
report("Mixer set to %d Hz, %dbit, %s%s%s\n", opt.rate,
opt.format & XMP_FORMAT_8BIT ? 8 : 16,
opt.interp == XMP_INTERP_LINEAR ? "linear interpolated " :
opt.interp == XMP_INTERP_SPLINE ? "cubic spline interpolated " : "",
opt.format & XMP_FORMAT_MONO ? "mono" : "stereo",
opt.dsp & XMP_DSP_LOWPASS ? "" : " (no filter)");
}
if (options.probeonly) {
if (opt.probeonly) {
exit(EXIT_SUCCESS);
}
if (options.random) {
if (opt.random) {
shuffle(argc - optind + 1, &argv[optind - 1]);
}
@ -263,13 +263,13 @@ int main(int argc, char **argv)
skipprev = 0;
if (options.ins_path) {
setenv("XMP_INSTRUMENT_PATH", options.ins_path, 1);
if (opt.ins_path) {
setenv("XMP_INSTRUMENT_PATH", opt.ins_path, 1);
}
lf_flag = 0;
for (first = optind; optind < argc; optind++) {
if (options.verbose > 0) {
if (opt.verbose > 0) {
if (lf_flag)
report("\n");
lf_flag = 1;
@ -278,6 +278,7 @@ int main(int argc, char **argv)
}
val = xmp_load_module(handle, argv[optind]);
if (val < 0) {
char *msg;
@ -311,37 +312,47 @@ int main(int argc, char **argv)
}
skipprev = 0;
control.time = 0.0;
control.loop = options.loop;
control.loop = opt.loop;
if (xmp_start_player(handle, options.rate, options.format) == 0) {
xmp_set_mixer(handle, XMP_MIXER_INTERP, options.interp);
xmp_set_mixer(handle, XMP_MIXER_DSP, options.dsp);
if (xmp_start_player(handle, opt.rate, opt.format) == 0) {
xmp_set_player(handle, XMP_PLAYER_INTERP, opt.interp);
xmp_set_player(handle, XMP_PLAYER_DSP, opt.dsp);
if (options.mix >= 0) {
xmp_set_mixer(handle, XMP_MIXER_MIX, options.mix);
if (opt.mix >= 0) {
xmp_set_player(handle, XMP_PLAYER_MIX, opt.mix);
}
if (options.reverse) {
int mix = xmp_get_mixer(handle, XMP_MIXER_MIX);
xmp_set_mixer(handle, XMP_MIXER_MIX, -mix);
if (opt.reverse) {
int mix;
mix = xmp_get_player(handle, XMP_PLAYER_MIX);
xmp_set_player(handle, XMP_PLAYER_MIX, -mix);
}
xmp_set_position(handle, options.start);
xmp_set_position(handle, opt.start);
/* Mute channels */
for (i = 0; i < XMP_MAX_CHANNELS; i++) {
xmp_channel_mute(handle, i, options.mute[i]);
xmp_channel_mute(handle, i, opt.mute[i]);
}
/* Change timing if vblank specified */
if (opt.vblank) {
xmp_set_player(handle, XMP_PLAYER_TIMING,
XMP_TIMING_VBLANK);
xmp_scan_module(handle);
}
/* Show module data */
xmp_get_module_info(handle, &mi);
if (options.verbose > 0) {
if (opt.verbose > 0) {
info_mod(&mi);
}
if (options.verbose > 1) {
if (opt.verbose > 1) {
info_instruments(&mi);
}
@ -351,14 +362,14 @@ int main(int argc, char **argv)
info_frame_init();
fi.loop_count = 0;
while (!options.info && xmp_play_frame(handle) == 0) {
while (!opt.info && xmp_play_frame(handle) == 0) {
int old_loop = fi.loop_count;
xmp_get_frame_info(handle, &fi);
if (!control.loop && old_loop != fi.loop_count)
break;
if (!background && options.verbose > 0) {
if (!background && opt.verbose > 0) {
info_frame(&mi, &fi, &control, refresh_status);
refresh_status = 0;
}
@ -367,7 +378,7 @@ int main(int argc, char **argv)
sound->play(fi.buffer, fi.buffer_size);
if (!background && !options.nocmd) {
if (!background && !opt.nocmd) {
read_command(handle, &control);
if (control.display) {
@ -377,15 +388,15 @@ int main(int argc, char **argv)
}
}
if (options.max_time > 0 &&
control.time > options.max_time) {
if (opt.max_time > 0 &&
control.time > opt.max_time) {
break;
}
check_pause(handle, &control, &mi, &fi,
options.verbose);
opt.verbose);
options.start = 0;
opt.start = 0;
}
xmp_end_player(handle);
@ -393,7 +404,7 @@ int main(int argc, char **argv)
xmp_release_module(handle);
if (!options.info) {
if (!opt.info) {
report("\n");
}

@ -31,11 +31,8 @@ enum {
OPT_FX9BUG = 0x105,
OPT_PROBEONLY,
OPT_LOADONLY,
OPT_STDOUT,
OPT_STEREO,
OPT_NOCMD,
OPT_FIXLOOP,
OPT_SHOWTIME,
OPT_VBLANK
};
static void usage(char *s)
@ -71,6 +68,7 @@ static void usage(char *s)
" -S --solo ch-list Set channels to solo mode\n"
" -s --start num Start from the specified order\n"
" -t --time num Maximum playing time in seconds\n"
" --vblank Force vblank timing in Amiga modules\n"
"\nMixer options:\n"
" -a --amplify {0|1|2|3} Amplification factor: 0=Normal, 1=x2, 2=x4, 3=x8\n"
" -b --bits {8|16} Software mixer resolution (8 or 16 bits)\n"
@ -125,6 +123,7 @@ static struct option lopt[] = {
{ "tempo", 1, 0, 'T' },
{ "time", 1, 0, 't' },
{ "unsigned", 0, 0, 'u' },
{ "vblank", 0, 0, OPT_VBLANK },
{ "version", 0, 0, 'V' },
{ "verbose", 0, 0, 'v' },
{ NULL, 0, 0, 0 }
@ -266,6 +265,9 @@ void get_options(int argc, char **argv, struct options *options)
case 'u':
options->format |= XMP_FORMAT_UNSIGNED;
break;
case OPT_VBLANK:
options->vblank = 1;
break;
case 'V':
puts("Extended Module Player " VERSION);
exit(0);

@ -31,6 +31,7 @@ xmp - Extended Module Player
[\fB-s, --start\fP \fIpos\fP]
[\fB-t, --time\fP \fItime\fP]
[\fB-u, --unsigned\fP]
[\fB--vblank\fP]
[\fB-V, --version\fP]
[\fB-v, --verbose\fP]
\fImodules\fP
@ -106,6 +107,8 @@ Specifies the maximum playing time to \fItime\fP seconds\&.
.IP "\fB-u, --unsigned\fP"
Tell the software mixer to use unsigned samples when mixing to
a file (default is signed)\&.
.IP "\fB--vblank\fP"
Force Amiga vblank-based timing (no CIA tempo setting)\&.
.IP "\fB-V, --version\fP"
Print version information\&.
.IP "\fB-v, --verbose\fP"

Loading…
Cancel
Save