2014-11-10 13:49:28 -02:00
|
|
|
#include "test.h"
|
|
|
|
|
#undef TEST
|
|
|
|
|
#include "../src/player.h"
|
|
|
|
|
#include "../src/mixer.h"
|
|
|
|
|
#include "../src/virtual.h"
|
|
|
|
|
|
2021-07-28 18:37:00 +03:00
|
|
|
static void _compare_mixer_data(const char *mod, const char *data, int loops, int ignore_rv)
|
2014-11-10 13:49:28 -02:00
|
|
|
{
|
|
|
|
|
xmp_context opaque;
|
|
|
|
|
struct context_data *ctx;
|
2022-01-24 11:53:05 -07:00
|
|
|
struct player_data *p;
|
|
|
|
|
struct mixer_voice *vi;
|
2014-11-10 13:49:28 -02:00
|
|
|
struct xmp_frame_info fi;
|
2022-02-10 02:31:38 -07:00
|
|
|
int time, row, frame, chan, period, note, ins, vol, pan, pos0, cutoff, resonance;
|
2014-11-10 13:49:28 -02:00
|
|
|
char line[200];
|
|
|
|
|
FILE *f;
|
2014-11-29 18:59:33 -02:00
|
|
|
int i, voc, ret;
|
2022-02-10 02:31:38 -07:00
|
|
|
int max_channels;
|
2014-11-10 13:49:28 -02:00
|
|
|
|
|
|
|
|
f = fopen(data, "r");
|
2014-11-29 18:59:33 -02:00
|
|
|
fail_unless(f != NULL, "can't open data file");
|
2014-11-10 13:49:28 -02:00
|
|
|
|
|
|
|
|
opaque = xmp_create_context();
|
2014-11-29 18:59:33 -02:00
|
|
|
fail_unless(opaque != NULL, "can't create context");
|
|
|
|
|
|
|
|
|
|
ret = xmp_load_module(opaque, mod);
|
|
|
|
|
fail_unless(ret == 0, "can't load module");
|
2014-11-10 13:49:28 -02:00
|
|
|
|
|
|
|
|
ctx = (struct context_data *)opaque;
|
|
|
|
|
p = &ctx->p;
|
|
|
|
|
|
|
|
|
|
xmp_start_player(opaque, 44100, 0);
|
|
|
|
|
xmp_set_player(opaque, XMP_PLAYER_MIX, 100);
|
|
|
|
|
|
2022-02-10 02:31:38 -07:00
|
|
|
max_channels = p->virt.virt_channels;
|
|
|
|
|
|
2014-11-10 13:49:28 -02:00
|
|
|
while (1) {
|
|
|
|
|
xmp_play_frame(opaque);
|
|
|
|
|
xmp_get_frame_info(opaque, &fi);
|
2015-01-03 19:16:48 -02:00
|
|
|
if (fi.loop_count >= loops)
|
2014-11-10 13:49:28 -02:00
|
|
|
break;
|
|
|
|
|
|
2022-02-10 02:31:38 -07:00
|
|
|
for (i = 0; i < max_channels; i++) {
|
|
|
|
|
/* Channel info doesn't get updated for NNA channels,
|
|
|
|
|
* need to get the info period from the channel data */
|
|
|
|
|
/*struct xmp_channel_info *ci = &fi.channel_info[i];*/
|
2014-11-10 13:49:28 -02:00
|
|
|
struct channel_data *xc = &p->xc_data[i];
|
2022-02-10 02:31:38 -07:00
|
|
|
int ci_period = xc->info_period;
|
2014-11-10 13:49:28 -02:00
|
|
|
int num;
|
|
|
|
|
|
|
|
|
|
voc = map_channel(p, i);
|
|
|
|
|
if (voc < 0 || TEST_NOTE(NOTE_SAMPLE_END))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
vi = &p->virt.voice_array[voc];
|
|
|
|
|
|
2016-07-09 23:53:35 -03:00
|
|
|
#if 1
|
2021-07-31 19:33:36 -06:00
|
|
|
fail_unless(fgets(line, 200, f) != NULL, "early EOF");
|
2022-02-10 02:31:38 -07:00
|
|
|
num = sscanf(line, "%d %d %d %d %d %d %d %d %d %d %d %d",
|
2014-11-10 13:49:28 -02:00
|
|
|
&time, &row, &frame, &chan, &period,
|
2022-02-10 02:31:38 -07:00
|
|
|
¬e, &ins, &vol, &pan, &pos0, &cutoff, &resonance);
|
2014-11-10 13:49:28 -02:00
|
|
|
|
2020-11-02 11:10:02 +03:00
|
|
|
/* Allow some error in values derived from floating point math. */
|
|
|
|
|
fail_unless(abs(fi.time - time) <= 1, "time mismatch");
|
2014-11-10 13:49:28 -02:00
|
|
|
fail_unless(fi.row == row, "row mismatch");
|
|
|
|
|
fail_unless(fi.frame == frame, "frame mismatch");
|
2014-11-26 16:24:46 -02:00
|
|
|
fail_unless(i == chan, "channel mismatch");
|
2022-02-10 02:31:38 -07:00
|
|
|
fail_unless(ci_period == period, "period mismatch");
|
2014-11-10 13:49:28 -02:00
|
|
|
fail_unless(vi->note == note, "note mismatch");
|
|
|
|
|
fail_unless(vi->ins == ins, "instrument");
|
2015-02-18 19:59:20 -02:00
|
|
|
if (!ignore_rv) {
|
|
|
|
|
fail_unless(vi->vol == vol, "volume mismatch");
|
2015-02-18 14:10:55 -02:00
|
|
|
fail_unless(vi->pan == pan, "pan mismatch");
|
|
|
|
|
}
|
2022-01-24 11:53:05 -07:00
|
|
|
/* x87 precision edge cases can slightly change loop
|
|
|
|
|
* wrapping behavior, which the abs() can't catch. */
|
|
|
|
|
if ((vi->pos0 == vi->start && pos0 == vi->end) ||
|
|
|
|
|
(vi->pos0 == vi->end && pos0 == vi->start)) {
|
|
|
|
|
pos0 = vi->pos0;
|
|
|
|
|
}
|
2020-11-02 11:10:02 +03:00
|
|
|
fail_unless(abs(vi->pos0 - pos0) <= 1, "position mismatch");
|
2014-11-10 13:49:28 -02:00
|
|
|
if (num >= 11) {
|
2022-02-07 18:39:26 -07:00
|
|
|
if (cutoff >= 254 && vi->filter.cutoff >= 254) {
|
|
|
|
|
cutoff = vi->filter.cutoff;
|
|
|
|
|
}
|
2014-11-10 13:49:28 -02:00
|
|
|
fail_unless(vi->filter.cutoff == cutoff,
|
|
|
|
|
"cutoff mismatch");
|
|
|
|
|
}
|
2022-02-10 02:31:38 -07:00
|
|
|
if (num >= 12) {
|
|
|
|
|
fail_unless(vi->filter.resonance == resonance,
|
|
|
|
|
"resonance mismatch");
|
|
|
|
|
}
|
2016-07-09 23:53:35 -03:00
|
|
|
#else
|
2022-02-10 02:31:38 -07:00
|
|
|
fprintf(f, "%d %d %d %d %d %d %d %d %d %d %d %d\n",
|
|
|
|
|
fi.time, fi.row, fi.frame, i, xc->info_period,
|
|
|
|
|
vi->note, vi->ins, vi->vol, vi->pan, vi->pos0,
|
|
|
|
|
vi->filter.cutoff, vi->filter.resonance);
|
2016-07-09 23:53:35 -03:00
|
|
|
#endif
|
2014-11-10 13:49:28 -02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-31 19:33:36 -06:00
|
|
|
if (fgets(line, 200, f) != NULL)
|
|
|
|
|
fail_unless(line[0] == '\0', "not end of data file");
|
2016-07-09 23:53:35 -03:00
|
|
|
//fail_unless(feof(f), "not end of data file");
|
2014-11-10 13:49:28 -02:00
|
|
|
|
|
|
|
|
xmp_end_player(opaque);
|
|
|
|
|
xmp_release_module(opaque);
|
|
|
|
|
xmp_free_context(opaque);
|
|
|
|
|
}
|
2015-01-03 19:16:48 -02:00
|
|
|
|
2021-07-28 18:37:00 +03:00
|
|
|
void compare_mixer_data(const char *mod, const char *data)
|
2015-01-03 19:16:48 -02:00
|
|
|
{
|
2015-02-18 14:10:55 -02:00
|
|
|
_compare_mixer_data(mod, data, 1, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-28 18:37:00 +03:00
|
|
|
void compare_mixer_data_loops(const char *mod, const char *data, int loops)
|
2015-02-18 14:10:55 -02:00
|
|
|
{
|
|
|
|
|
_compare_mixer_data(mod, data, loops, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-28 18:37:00 +03:00
|
|
|
void compare_mixer_data_no_rv(const char *mod, const char *data)
|
2015-02-18 14:10:55 -02:00
|
|
|
{
|
|
|
|
|
_compare_mixer_data(mod, data, 1, 1);
|
2015-01-03 19:16:48 -02:00
|
|
|
}
|