From 9651284b91eddf9bdd23d66e770522e74ad6c09e Mon Sep 17 00:00:00 2001 From: Claudio Matsuoka Date: Sat, 4 Jun 2016 22:00:53 -0300 Subject: [PATCH] Add support for libxmp 4.4 player mode setting Signed-off-by: Claudio Matsuoka --- Changelog | 4 ++++ configure.ac | 6 +++--- src/common.h | 10 +++++++++- src/main.c | 9 +++++++++ src/modules.conf | 18 +++--------------- src/options.c | 43 ++++++++++++++++++++++++++++++++++++++----- src/read_config.c | 14 ++++++++++++++ src/xmp.1 | 22 +++++++++++++++------- 8 files changed, 95 insertions(+), 31 deletions(-) diff --git a/Changelog b/Changelog index 2b34a21..7027ca2 100644 --- a/Changelog +++ b/Changelog @@ -1,6 +1,10 @@ Stable versions --------------- +4.1.0 (): + - Add option to force tracker emulation (requires libxmp 4.4) + - Remove option --offset-bug-emulation + 4.0.11 (20160306): - Mark surround channels in channel list - Address errors reported by Coverity Scan diff --git a/configure.ac b/configure.ac index baebebc..550bd9e 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([xmp], [4.0.11]) +AC_INIT([xmp], [4.1.0]) AM_SILENT_RULES([yes]) AC_CONFIG_AUX_DIR([build-aux]) 0>confdefs.h @@ -29,9 +29,9 @@ esac AC_PROG_INSTALL AM_INIT_AUTOMAKE([foreign subdir-objects tar-pax]) -PKG_CHECK_MODULES([libxmp], [libxmp >= 4.3], +PKG_CHECK_MODULES([libxmp], [libxmp >= 4.4], AC_CHECK_LIB(xmp, xmp_version, [], [exit 1]), - [echo "You need libxmp version 4.3 or later to build this package"; exit 1]) + [echo "You need libxmp version 4.4 or later to build this package"; exit 1]) dnl Don't use things like /usr/etc or /usr/var diff --git a/src/common.h b/src/common.h index 36ea3f7..1777ba3 100644 --- a/src/common.h +++ b/src/common.h @@ -15,8 +15,15 @@ #define getch _getch #endif +#define NUM_MODES 13 #define MAX_DRV_PARM 20 +struct player_mode { + char *name; + char *desc; + int mode; +}; + struct options { int start; /* start order */ int amplify; /* amplification factor */ @@ -31,7 +38,7 @@ struct options { int random; /* play in random order */ int reverse; /* reverse stereo channels */ int vblank; /* vblank flag */ - int fx9bug; /* fx9bug flag */ + int fx9bug; /* fx9bug flag -- DEPRECATED */ int fixloop; /* fixloop flag */ int verbose; /* verbosity level */ int silent; /* silent output */ @@ -43,6 +50,7 @@ struct options { int sequence; /* sequence to play */ int explore; /* play all sequences in module */ int show_comment; /* show module comment text */ + int player_mode; /* force tracker emulation */ char *driver_id; /* sound driver ID */ char *out_file; /* output file name */ char *ins_path; /* instrument path */ diff --git a/src/main.c b/src/main.c index 6a019eb..6bffcc1 100644 --- a/src/main.c +++ b/src/main.c @@ -229,6 +229,7 @@ int main(int argc, char **argv) opt.driver_id = NULL; opt.interp = XMP_INTERP_SPLINE; opt.dsp = XMP_DSP_LOWPASS; + opt.player_mode = XMP_MODE_AUTO; /* read configuration file */ if (!opt.norc) { @@ -251,6 +252,13 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } + if (opt.player_mode < 0) { + fprintf(stderr, "%s: unknown player mode\n" + "Use `%s --help' for more information.\n", + argv[0], argv[0]); + exit(EXIT_FAILURE); + } + if (opt.silent) { opt.driver_id = "null"; } @@ -395,6 +403,7 @@ int main(int argc, char **argv) if (xmp_start_player(xc, opt.rate, opt.format) == 0) { xmp_set_player(xc, XMP_PLAYER_INTERP, opt.interp); xmp_set_player(xc, XMP_PLAYER_DSP, opt.dsp); + xmp_set_player(xc, XMP_PLAYER_MODE, opt.player_mode); played = 1; diff --git a/src/modules.conf b/src/modules.conf index 8c51b92..84f3df9 100644 --- a/src/modules.conf +++ b/src/modules.conf @@ -9,25 +9,13 @@ # amplify = <0|1|2|3> Amplification factor (default is 1) # filter = yes/no Enable filters (affects IT only) # fixloop = yes/no Use sample loop start value / 2 -# fx9bug = yes/no Protracker 2.x effect 9 bug emulation # interpolation = Software mixer interpolation +# mode = Force tracker emulation # mono = yes/no Mono output # mix = value Stereo channel separation (0 - 100) # reverse = yes/no Reverse L/R stereo channels # vblank = yes/no Force vblank timing instead of CIA # "No Mercy" by Alf/VTL (added by Martin Willers) -[366ec0fa962aebee034aa2dbaa49aaea] -fx9bug = yes - -# mod.souvenir of china -[93f146aeb758c39d8b5fbc98bf237a43] -fixloop = yes - -# "siedler ii" (added by Daniel Ã…kerud) -[70aa034dfb2f1f73d9fdbafe131bb701] -vblank = yes - -# "klisje paa klisje" (added by Kjetil Torgrim Homme) -[e998012c700eb43af0321711305829b2] -vblank = yes +#[366ec0fa962aebee034aa2dbaa49aaea] +#mode = protracker diff --git a/src/options.c b/src/options.c index 295a257..b7eda70 100644 --- a/src/options.c +++ b/src/options.c @@ -38,10 +38,26 @@ enum { OPT_LOOPALL, }; +struct player_mode pmode[] = { + { "auto", "Autodetect", XMP_MODE_AUTO }, + { "mod", "Generic MOD player", XMP_MODE_MOD }, + { "noisetracker", "Noisetracker", XMP_MODE_NOISETRACKER }, + { "protracker", "Protracker 1/2", XMP_MODE_PROTRACKER }, + { "s3m", "Generic S3M player", XMP_MODE_S3M }, + { "st3", "Scream Tracker 3", XMP_MODE_ST3 }, + { "st3gus", "Scream Tracker 3 with GUS", XMP_MODE_ST3GUS }, + { "xm", "Generic XM player", XMP_MODE_XM }, + { "ft2", "Fasttracker II", XMP_MODE_FT2 }, + { "it", "Impulse Tracker", XMP_MODE_IT }, + { "itsmp", "Impulse Tracker sample mode", XMP_MODE_ITSMP }, + { NULL, NULL, 0 } +}; + static void usage(char *s, struct options *options) { struct list_head *head; struct sound_driver *sd; + struct player_mode *pm; const char *const *hlp; printf("Usage: %s [options] [modules]\n", s); @@ -61,16 +77,21 @@ static void usage(char *s, struct options *options) printf(" -D%-20.20s %s\n", hlp[0], hlp[1]); } + printf("\nAvailable player modes:\n"); + for (pm = pmode; pm->name != NULL; pm++) { + printf(" %-22.22s %s\n", pm->name, pm->desc); + } + printf("\nPlayer control options:\n" " -D parameter[=val] Pass configuration parameter to the output driver\n" " -d --driver name Force output to the specified device\n" +" -e --player-mode mode Force tracker emulation (default auto)\n" " --fix-sample-loops Use sample loop start /2 in MOD/UNIC/NP3\n" " -l --loop Enable module looping\n" " --loop-all Loop over entire module list\n" " -M --mute ch-list Mute the specified channels\n" " --nocmd Disable interactive commands\n" " --norc Don't read configuration files\n" -" --offset-bug-emulation Emulate Protracker 2.x bug in effect 9\n" " -R --random Random order playing\n" " -S --solo ch-list Set channels to solo mode\n" " -s --start num Start from the specified order\n" @@ -126,9 +147,10 @@ static const struct option lopt[] = { { "nocmd", 0, 0, OPT_NOCMD }, { "norc", 0, 0, OPT_NORC }, { "nofilter", 0, 0, 'F' }, - { "offset-bug-emulation",0, 0, OPT_FX9BUG }, + /* { "offset-bug-emulation",0, 0, OPT_FX9BUG }, */ { "output-file", 1, 0, 'o' }, { "pan", 1, 0, 'P' }, + { "player-mode", 1, 0, 'e' }, { "probe-only", 0, 0, OPT_PROBEONLY }, { "load-only", 0, 0, OPT_LOADONLY }, { "quiet", 0, 0, 'q' }, @@ -151,10 +173,11 @@ static const struct option lopt[] = { void get_options(int argc, char **argv, struct options *options) { + struct player_mode *pm; int optidx = 0; int o; -#define OPTIONS "a:b:CcD:d:Ff:hI:i:LlM:mNo:P:p:qRrS:s:T:t:uVvZz:" +#define OPTIONS "a:b:CcD:d:e:Ff:hI:i:LlM:mNo:P:p:qRrS:s:T:t:uVvZz:" while ((o = getopt_long(argc, argv, OPTIONS, lopt, &optidx)) != -1) { switch (o) { case 'a': @@ -178,6 +201,16 @@ void get_options(int argc, char **argv, struct options *options) break; case 'd': options->driver_id = optarg; + break; + case 'e': + for (pm = pmode; pm->name != NULL; pm++) { + if (!strcmp(optarg, pm->name)) { + options->player_mode = pm->mode; + break; + } + options->player_mode = -1; + } + break; case 'F': options->dsp &= ~XMP_DSP_LOWPASS; @@ -245,9 +278,9 @@ void get_options(int argc, char **argv, struct options *options) options->driver_id = "file"; } break; - case OPT_FX9BUG: + /* case OPT_FX9BUG: options->fx9bug = 1; - break; + break; */ case 'P': options->mix = strtoul(optarg, NULL, 0); if (options->mix < 0) diff --git a/src/read_config.c b/src/read_config.c index 8deb8fa..3caa537 100644 --- a/src/read_config.c +++ b/src/read_config.c @@ -17,6 +17,8 @@ #include #endif +extern struct player_mode pmode[]; + static char driver[32]; static char instrument_path[256]; @@ -190,6 +192,7 @@ static void parse_modconf(struct options *o, char *confname, unsigned char *md5) { FILE *rc; char *hash, *var, *val, line[256]; + struct player_mode *pm; int active = 0; if ((rc = fopen(confname, "r")) == NULL) @@ -250,6 +253,17 @@ static void parse_modconf(struct options *o, char *confname, unsigned char *md5) "type \"%s\"\n", confname, val); } } + + if (!strcmp(var, "mode")) { + for (pm = pmode; pm->name != NULL; pm++) { + if (!strcmp(val, pm->name)) { + o->player_mode = pm->mode; + break; + } + fprintf(stderr, "%s: unknown player mode " + "\"%s\"\n", confname, val); + } + } } fclose(rc); diff --git a/src/xmp.1 b/src/xmp.1 index 60637ea..b933a72 100644 --- a/src/xmp.1 +++ b/src/xmp.1 @@ -1,4 +1,4 @@ -.TH "XMP" "1" "Version 4\&.0\&.11" "Mar 2016" "Extended Module Player" +.TH "XMP" "1" "Version 4\&.1\&.0" "Jun 2016" "Extended Module Player" .PP .SH "NAME" xmp - Extended Module Player @@ -11,6 +11,7 @@ xmp - Extended Module Player [\fB\-c, \-\-stdout\fP] [\fB\-D\fP \fIdevice-specific parameters\fP] [\fB\-d, \-\-driver\fP \fIdriver\fP] +[\fB\-e, \-\-player\-mode\fP \fImode\fP] [\fB\-F, \-\-nofilter\fP] [\fB\-f, \-\-frequency\fP \fIrate\fP] [\fB\-\-fix\-sample\-loop\fP] @@ -26,7 +27,6 @@ xmp - Extended Module Player [\fB\-N, \-\-null\fP] [\fB\-\-nocmd\fP] [\fB\-o, \-\-output\-file\fP \fIfilename\fP] -[\fB\-\-offset\-bug\-emulation\fP] [\fB\-P, \-\-pan\fP \fInum\fP] [\fB\-p, \-\-default\-pan\fP \fInum\fP] [\fB\-\-probe\-only\fP] @@ -68,6 +68,16 @@ list of known parameters\&. .IP "\fB\-d, \-\-driver\fP \fIdriver\fP" Select the output driver\&. If not specified, \fBxmp\fP will try to probe each available driver\&. +.IP "\fB\-e, \-\-player\-mode\fP \fImode\fP" +Force play mode or emulation of a specific tracker\&. Valid player modes +are\&: \fBauto\fP (autodetection)\&, \fBmod\fP (generic mod player mode)\&, +\fBnoisetracker\fP\&, \fBprotracker\fP (Protracker 1/2)\&, \fBs3m\fP (generic +S3M player mode)\&, \fBst3\fP (Scream Tracker 3)\&, \fBst3gus\fP (Scream +Tracker 3 with GUS card)\&, \fBxm\fP (generic XM player mode)\&, \fBft2\fP +(Fasttracker II)\&, \fBit\fP (Impulse Tracker)\&, or \fBitsmp\fP (Impulse +Tracker in sample mode)\&. When a specific tracker is specified, \fBxmp\fP +will try to emulate quirks and bugs for accurate replay\&. Default is +autodetection. .IP "\fB\-F, \-\-nofilter\fP" Disable IT lowpass filter effect and envelopes. .IP "\fB\-f, \-\-frequency\fP \fIrate\fP" @@ -81,9 +91,9 @@ Show a short summary of command-line options\&. .IP "\fB\-I, \-\-instrument\-path\fP \fIpath\fP" Set the pathname to the directory containing external samples\&. .IP "\fB\-i, \-\-interpolation\fP \fItype\fP" -Select interpolation type. Available types are \fInearest\fP for -nearest-neighbor interpolation\&, \fIlinear\fI for linear interpolation\&, and -\fIspline\fI for cubic spline interpolation\&. Default is cubic spline\&. +Select interpolation type. Available types are \fBnearest\fP for +nearest-neighbor interpolation\&, \fBlinear\fP for linear interpolation\&, and +\fBspline\fP for cubic spline interpolation\&. Default is cubic spline\&. .IP "\fB\-\-load\-only\fP" Load module and exit\&. .IP "\fB\-L, \-\-list\-formats\fP" @@ -104,8 +114,6 @@ Disable interactive commands\&. .IP "\fB\-o, \-\-output\-file\fP \fIfilename\fP" Set the output file name when mixing to raw or WAV files\&. If \'-\' is given as the file name, the output will be sent to stdout\&. -.IP "\fB\-\-offset\-bug\-emulation\fP" -Emulate Protracker 2.x handling of effect 0x09 (set sample offset)\&. .IP "\fB\-P, \-\-pan\fP \fInum\fP" Set the percentual panning amplitude\&. .IP "\fB\-P, \-\-default\-pan\fP \fInum\fP"