Add round 1 of tests
This commit is contained in:
parent
6a5fe5e024
commit
be463856db
5 changed files with 210 additions and 68 deletions
81
test/all.js
81
test/all.js
|
|
@ -1,65 +1,19 @@
|
||||||
window = {};
|
window = {};
|
||||||
|
|
||||||
require('../xm.js', window);
|
require('../xm.js');
|
||||||
require('../xmeffects.js', window);
|
require('../xmeffects.js');
|
||||||
|
|
||||||
var XMPlayer = window.XMPlayer;
|
var XMPlayer = window.XMPlayer;
|
||||||
|
|
||||||
// set up basic blank single-channel, single-pattern XM
|
tests = {};
|
||||||
function ResetXMData() {
|
testdata = require('./testdata.js');
|
||||||
var xm = {};
|
|
||||||
window.XMPlayer.xm = xm;
|
|
||||||
xm.channelinfo = [];
|
|
||||||
xm.songname = "test song";
|
|
||||||
xm.song_looppos = 0;
|
|
||||||
xm.nchan = 1;
|
|
||||||
xm.flags = 1;
|
|
||||||
xm.tempo = 3;
|
|
||||||
xm.bpm = 125;
|
|
||||||
xm.channelinfo.push({
|
|
||||||
number: 0,
|
|
||||||
filterstate: new Float32Array(3),
|
|
||||||
vol: 0,
|
|
||||||
pan: 128,
|
|
||||||
period: 1920 - 48*16,
|
|
||||||
vL: 0, vR: 0,
|
|
||||||
vLprev: 0, vRprev: 0,
|
|
||||||
mute: 0,
|
|
||||||
volE: 0, panE: 0,
|
|
||||||
retrig: 0,
|
|
||||||
vibratodepth: 1,
|
|
||||||
vibratospeed: 1,
|
|
||||||
});
|
|
||||||
xm.songpats = [0];
|
|
||||||
// 1 channel, 2 row blank pattern
|
|
||||||
xm.patterns = [
|
|
||||||
[[[-1, -1, -1, 0, 0]]],
|
|
||||||
[[[-1, -1, -1, 0, 0]]]];
|
|
||||||
xm.instruments = [];
|
|
||||||
xm.instruments.push({
|
|
||||||
'name': "test instrument",
|
|
||||||
'number': 0,
|
|
||||||
'samples': [
|
|
||||||
{ 'len': 256, 'loop': 0,
|
|
||||||
'looplen': 256, 'note': 0, 'fine': 0,
|
|
||||||
'pan': 128, 'type': 0, 'vol': 64,
|
|
||||||
'sampledata': new Float32Array(256)
|
|
||||||
}
|
|
||||||
],
|
|
||||||
'samplemap': new Uint8Array(96),
|
|
||||||
'env_vol': new XMPlayer.Envelope([0, 64, 1, 0], 2, 0, 0, 0),
|
|
||||||
'env_pan': new XMPlayer.Envelope([0, 32], 0, 0, 0, 0)
|
|
||||||
});
|
|
||||||
// reset song position
|
|
||||||
XMPlayer.cur_songpos = -1;
|
|
||||||
XMPlayer.cur_pat = -1;
|
|
||||||
XMPlayer.cur_tick = xm.tempo;
|
|
||||||
return xm;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// test TODO:
|
||||||
|
// - audio output sample positions after ticks
|
||||||
|
// - unit test for envelopes
|
||||||
|
//
|
||||||
// using assert passed to the test function that just logs failures
|
// using assert passed to the test function that just logs failures
|
||||||
exports['test XM startup'] = function(assert) {
|
tests['test XM startup'] = function(assert) {
|
||||||
ResetXMData();
|
testdata.resetXMData();
|
||||||
XMPlayer.nextTick();
|
XMPlayer.nextTick();
|
||||||
assert.equal(XMPlayer.cur_songpos, 0, 'advance to initial song position');
|
assert.equal(XMPlayer.cur_songpos, 0, 'advance to initial song position');
|
||||||
assert.equal(XMPlayer.cur_pat, 0, 'advance to pattern 0');
|
assert.equal(XMPlayer.cur_pat, 0, 'advance to pattern 0');
|
||||||
|
|
@ -67,16 +21,7 @@ exports['test XM startup'] = function(assert) {
|
||||||
assert.equal(XMPlayer.cur_row, 1, 'advance to row 1');
|
assert.equal(XMPlayer.cur_row, 1, 'advance to row 1');
|
||||||
};
|
};
|
||||||
|
|
||||||
exports['test note on'] = function(assert) {
|
require('./instrument.js');
|
||||||
var xm = ResetXMData();
|
require('./effects.js');
|
||||||
// [row][column][channel]
|
|
||||||
xm.patterns[0][0][0] = [48, 1, 0x10 + 33, 0, 0]; // C-4 1 40 000
|
|
||||||
XMPlayer.nextTick();
|
|
||||||
var ch = xm.channelinfo[0];
|
|
||||||
assert.equal(ch.note, 48, 'set note');
|
|
||||||
assert.equal(ch.period, 1152, 'channel period');
|
|
||||||
assert.equal(ch.vol, 33, 'channel volume');
|
|
||||||
assert.equal(ch.samp, xm.instruments[0].samples[0], 'set sample');
|
|
||||||
};
|
|
||||||
|
|
||||||
if (module == require.main) require('test').run(exports);
|
if (module == require.main) require('test').run(tests);
|
||||||
|
|
|
||||||
85
test/effects.js
vendored
Normal file
85
test/effects.js
vendored
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
var XMPlayer = window.XMPlayer;
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// - portamento 3xx
|
||||||
|
// - vibrato 4xy
|
||||||
|
// - volume slide Axy
|
||||||
|
// - porta+vol 5xy
|
||||||
|
// - etc etc
|
||||||
|
|
||||||
|
tests['test 0xy arpeggio'] = function(assert) {
|
||||||
|
var xm = testdata.resetXMData();
|
||||||
|
// [pat][row][channel]
|
||||||
|
xm.patterns[0][0][0] = [48, 1, -1, 0, 0x4f]; // C-4 1 -- 04f
|
||||||
|
XMPlayer.xm.tempo = 4;
|
||||||
|
XMPlayer.nextTick();
|
||||||
|
var ch = xm.channelinfo[0];
|
||||||
|
assert.equal(ch.note, 48, 'note 0');
|
||||||
|
assert.equal(ch.period, 1152, 'row 0 tick 0 period 0');
|
||||||
|
XMPlayer.nextTick();
|
||||||
|
assert.equal(ch.period, 1152 - 16*4, 'row 0 tick 1 period 4');
|
||||||
|
XMPlayer.nextTick();
|
||||||
|
assert.equal(ch.period, 1152 - 16*15, 'row 0 tick 2 period f');
|
||||||
|
XMPlayer.nextTick();
|
||||||
|
assert.equal(ch.period, 1152 - 16*0, 'row 0 tick 3 period 0');
|
||||||
|
XMPlayer.nextTick();
|
||||||
|
assert.equal(ch.period, 1152 - 16*0, 'row 1 tick 0 period 0');
|
||||||
|
};
|
||||||
|
|
||||||
|
tests['test 1xx slide up'] = function(assert) {
|
||||||
|
var xm = testdata.resetXMData();
|
||||||
|
// [pat][row][channel]
|
||||||
|
xm.patterns[0][0][0] = [48, 1, -1, 1, 0x01]; // C-4 1 -- 101
|
||||||
|
xm.patterns[0][1][0] = [-1, -1, -1, 1, 0x00]; // --- -- -- 100
|
||||||
|
XMPlayer.xm.tempo = 3;
|
||||||
|
XMPlayer.nextTick();
|
||||||
|
var ch = xm.channelinfo[0];
|
||||||
|
assert.equal(ch.period, 1152, 'row 0 tick 0 period 0');
|
||||||
|
XMPlayer.nextTick();
|
||||||
|
assert.equal(ch.period, 1152 - 1, 'row 0 tick 1 period -1');
|
||||||
|
XMPlayer.nextTick();
|
||||||
|
assert.equal(ch.period, 1152 - 2, 'row 0 tick 2 period -2');
|
||||||
|
XMPlayer.nextTick();
|
||||||
|
assert.equal(ch.period, 1152 - 2, 'row 1 tick 0 period -2');
|
||||||
|
XMPlayer.nextTick();
|
||||||
|
assert.equal(ch.period, 1152 - 3, 'row 1 tick 1 period -3');
|
||||||
|
};
|
||||||
|
|
||||||
|
tests['test 2xx slide down'] = function(assert) {
|
||||||
|
var xm = testdata.resetXMData();
|
||||||
|
// [pat][row][channel]
|
||||||
|
xm.patterns[0][0][0] = [48, 1, -1, 2, 0x01]; // C-4 1 -- 201
|
||||||
|
xm.patterns[0][1][0] = [-1, -1, -1, 2, 0x00]; // --- -- -- 200
|
||||||
|
XMPlayer.xm.tempo = 3;
|
||||||
|
XMPlayer.nextTick();
|
||||||
|
var ch = xm.channelinfo[0];
|
||||||
|
assert.equal(ch.period, 1152, 'row 0 tick 0 period 0');
|
||||||
|
XMPlayer.nextTick();
|
||||||
|
assert.equal(ch.period, 1152 + 1, 'row 0 tick 1 period -1');
|
||||||
|
XMPlayer.nextTick();
|
||||||
|
assert.equal(ch.period, 1152 + 2, 'row 0 tick 2 period -2');
|
||||||
|
XMPlayer.nextTick();
|
||||||
|
assert.equal(ch.period, 1152 + 2, 'row 1 tick 0 period -2');
|
||||||
|
XMPlayer.nextTick();
|
||||||
|
assert.equal(ch.period, 1152 + 3, 'row 1 tick 1 period -3');
|
||||||
|
};
|
||||||
|
|
||||||
|
tests['test 3xx portamento'] = function(assert) {
|
||||||
|
var xm = testdata.resetXMData();
|
||||||
|
// [pat][row][channel]
|
||||||
|
xm.patterns[0][0][0] = [48, 1, -1, 0, 0x00]; // C-4 1 -- 000
|
||||||
|
xm.patterns[0][1][0] = [49, 1, -1, 3, 0x09]; // C#4 1 -- 309
|
||||||
|
XMPlayer.xm.tempo = 3;
|
||||||
|
XMPlayer.nextTick(); // row 0 tick 0
|
||||||
|
var ch = xm.channelinfo[0];
|
||||||
|
assert.equal(ch.period, 1152, 'row 0 tick 0 period 0');
|
||||||
|
XMPlayer.nextTick(); // row 0 tick 1
|
||||||
|
XMPlayer.nextTick(); // row 0 tick 2
|
||||||
|
XMPlayer.nextTick(); // row 1 tick 0
|
||||||
|
assert.equal(ch.period, 1152, 'row 1 tick 0 period 0');
|
||||||
|
XMPlayer.nextTick();
|
||||||
|
assert.equal(ch.period, 1152 - 9, 'row 1 tick 1 period -9');
|
||||||
|
XMPlayer.nextTick();
|
||||||
|
assert.equal(ch.period, 1152 - 16, 'row 1 tick 2 period -16');
|
||||||
|
};
|
||||||
|
|
||||||
55
test/instrument.js
Normal file
55
test/instrument.js
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
var XMPlayer = window.XMPlayer;
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// - test volume envelope (sustain, release)
|
||||||
|
// - test panning envelope
|
||||||
|
|
||||||
|
tests['test note on'] = function(assert) {
|
||||||
|
var xm = testdata.resetXMData();
|
||||||
|
// [pat][row][channel]
|
||||||
|
xm.patterns[0][0][0] = [48, 1, 0x10 + 0x33, 0, 0]; // C-4 1 33 000
|
||||||
|
XMPlayer.nextRow();
|
||||||
|
var ch = xm.channelinfo[0];
|
||||||
|
assert.equal(ch.note, 48, 'set note');
|
||||||
|
assert.equal(ch.period, 1152, 'channel period');
|
||||||
|
assert.equal(ch.vol, 0x33, 'channel volume');
|
||||||
|
assert.equal(ch.samp, xm.instruments[0].samples[0], 'set sample');
|
||||||
|
assert.equal(ch.off, 0, 'trigger offset');
|
||||||
|
};
|
||||||
|
|
||||||
|
tests['test instrument trigger'] = function(assert) {
|
||||||
|
var xm = testdata.resetXMData();
|
||||||
|
// [pat][row][channel]
|
||||||
|
xm.patterns[0][0][0] = [48, 1, 0x10 + 0x33, 0, 0]; // C-4 1 33 000
|
||||||
|
xm.patterns[0][1][0] = [-1, 1, -1, 0, 0]; // --- 1 -- 000
|
||||||
|
var ch = xm.channelinfo[0];
|
||||||
|
XMPlayer.nextRow();
|
||||||
|
ch.pan = 1; // forcibly override panning
|
||||||
|
ch.off = 100; // and sample offset
|
||||||
|
assert.equal(XMPlayer.cur_row, 1, 'row 1');
|
||||||
|
XMPlayer.nextRow();
|
||||||
|
assert.equal(XMPlayer.cur_row, 2, 'row 2');
|
||||||
|
assert.equal(ch.note, 48, 'note same after inst trigger');
|
||||||
|
assert.equal(ch.period, 1152, 'period same after inst trigger');
|
||||||
|
assert.equal(ch.vol, 64, 'vol reset after inst trigger');
|
||||||
|
assert.equal(ch.pan, 128, 'pan reset after inst trigger');
|
||||||
|
assert.equal(ch.samp, xm.instruments[0].samples[0], 'set sample');
|
||||||
|
assert.equal(ch.off, 0, 'set offset=0');
|
||||||
|
};
|
||||||
|
|
||||||
|
tests['test note trigger'] = function(assert) {
|
||||||
|
var xm = testdata.resetXMData();
|
||||||
|
// [pat][row][channel]
|
||||||
|
xm.patterns[0][0][0] = [48, 1, 0x10 + 0x33, 0, 0]; // C-4 1 33 000
|
||||||
|
xm.patterns[0][1][0] = [49, -1, -1, 0, 0]; // C#4 -- -- 000
|
||||||
|
var ch = xm.channelinfo[0];
|
||||||
|
XMPlayer.nextRow();
|
||||||
|
ch.pan = 1; // forcibly override panning
|
||||||
|
ch.off = 100; // and sample offset
|
||||||
|
XMPlayer.nextRow();
|
||||||
|
assert.equal(ch.note, 49, 'note updated after inst trigger');
|
||||||
|
assert.equal(ch.period, 1136, 'period updated after note trigger');
|
||||||
|
assert.equal(ch.vol, 0x33, 'vol not reset after note trigger');
|
||||||
|
assert.equal(ch.pan, 1, 'pan not reset after note trigger');
|
||||||
|
assert.equal(ch.off, 0, 'set offset=0');
|
||||||
|
};
|
||||||
56
test/testdata.js
Normal file
56
test/testdata.js
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
var XMPlayer = window.XMPlayer;
|
||||||
|
|
||||||
|
// set up basic blank single-channel, single-pattern XM
|
||||||
|
exports.resetXMData = function() {
|
||||||
|
var xm = {};
|
||||||
|
window.XMPlayer.xm = xm;
|
||||||
|
xm.channelinfo = [];
|
||||||
|
xm.songname = "test song";
|
||||||
|
xm.song_looppos = 0;
|
||||||
|
xm.nchan = 1;
|
||||||
|
xm.flags = 1;
|
||||||
|
xm.tempo = 3;
|
||||||
|
xm.bpm = 125;
|
||||||
|
xm.channelinfo.push({
|
||||||
|
number: 0,
|
||||||
|
filterstate: new Float32Array(3),
|
||||||
|
vol: 0,
|
||||||
|
pan: 128,
|
||||||
|
period: 1920 - 48*16,
|
||||||
|
vL: 0, vR: 0,
|
||||||
|
vLprev: 0, vRprev: 0,
|
||||||
|
mute: 0,
|
||||||
|
volE: 0, panE: 0,
|
||||||
|
retrig: 0,
|
||||||
|
vibratodepth: 1,
|
||||||
|
vibratospeed: 1,
|
||||||
|
});
|
||||||
|
xm.songpats = [0];
|
||||||
|
// 1 channel, 2 row blank pattern
|
||||||
|
xm.patterns = [
|
||||||
|
[
|
||||||
|
[[-1, -1, -1, 0, 0]],
|
||||||
|
[[-1, -1, -1, 0, 0]]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
xm.instruments = [];
|
||||||
|
xm.instruments.push({
|
||||||
|
'name': "test instrument",
|
||||||
|
'number': 0,
|
||||||
|
'samples': [
|
||||||
|
{ 'len': 256, 'loop': 0,
|
||||||
|
'looplen': 256, 'note': 0, 'fine': 0,
|
||||||
|
'pan': 128, 'type': 0, 'vol': 64,
|
||||||
|
'sampledata': new Float32Array(256)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'samplemap': new Uint8Array(96),
|
||||||
|
'env_vol': new XMPlayer.Envelope([0, 64, 1, 0], 2, 0, 0, 0),
|
||||||
|
'env_pan': new XMPlayer.Envelope([0, 32], 0, 0, 0, 0)
|
||||||
|
});
|
||||||
|
// reset song position
|
||||||
|
XMPlayer.cur_songpos = -1;
|
||||||
|
XMPlayer.cur_pat = -1;
|
||||||
|
XMPlayer.cur_tick = xm.tempo;
|
||||||
|
return xm;
|
||||||
|
};
|
||||||
1
xm.js
1
xm.js
|
|
@ -25,6 +25,7 @@ player.xm = {}; // contains all song data
|
||||||
|
|
||||||
// exposed for testing
|
// exposed for testing
|
||||||
player.nextTick = nextTick;
|
player.nextTick = nextTick;
|
||||||
|
player.nextRow = nextRow;
|
||||||
player.Envelope = Envelope;
|
player.Envelope = Envelope;
|
||||||
|
|
||||||
// for pretty-printing notes
|
// for pretty-printing notes
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue