From fb103e61bc527e7c71a67b28c1277db3d097de0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Hillerstr=C3=B6m?= Date: Sat, 21 Nov 2015 02:21:16 +0100 Subject: [PATCH 01/10] Read vibrato waveform type --- test/testdata.js | 1 + xm.js | 1 + xmeffects.js | 3 +++ 3 files changed, 5 insertions(+) diff --git a/test/testdata.js b/test/testdata.js index 8157cd9..c8dd629 100644 --- a/test/testdata.js +++ b/test/testdata.js @@ -25,6 +25,7 @@ exports.resetXMData = function() { vibratopos: 0, vibratodepth: 1, vibratospeed: 1, + vibratotype: 0, }); xm.songpats = [0]; // 1 channel, 2 row blank pattern diff --git a/xm.js b/xm.js index cb9868e..6af8432 100644 --- a/xm.js +++ b/xm.js @@ -697,6 +697,7 @@ function load(arrayBuf) { vibratopos: 0, vibratodepth: 1, vibratospeed: 1, + vibratotype: 0, }); } console.log("header len " + hlen); diff --git a/xmeffects.js b/xmeffects.js index 0e8a7f1..27d2eda 100644 --- a/xmeffects.js +++ b/xmeffects.js @@ -135,6 +135,9 @@ function eff_t0_e(ch, data) { // extended effects! case 2: // fine porta down ch.period += data; break; + case 4: // set vibrato waveform + ch.vibratotype = data & 0x07; + break; case 5: // finetune ch.fine = (data<<4) + data - 128; break; From 0e47b13d833b3a7e5f826b2af59f6cea2debf28a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Hillerstr=C3=B6m?= Date: Sat, 21 Nov 2015 02:26:04 +0100 Subject: [PATCH 02/10] Implement all vibrato waveforms --- xmeffects.js | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/xmeffects.js b/xmeffects.js index 27d2eda..dad153d 100644 --- a/xmeffects.js +++ b/xmeffects.js @@ -65,7 +65,7 @@ function eff_t0_4(ch, data) { // vibrato } function eff_t1_4(ch) { // vibrato - ch.periodoffset = Math.sin(ch.vibratopos * Math.PI / 32) * ch.vibratodepth; + ch.periodoffset = getVibratoDelta(ch.vibratotype, ch.vibratopos) * ch.vibratodepth; if (isNaN(ch.periodoffset)) { console.log("vibrato periodoffset NaN?", ch.vibratopos, ch.vibratospeed, ch.vibratodepth); @@ -75,6 +75,24 @@ function eff_t1_4(ch) { // vibrato ch.vibratopos &= 63; } +function getVibratoDelta(type, x) { + var delta = 0; + switch (type & 0x03) { + case 1: // sawtooth (ramp-down) + delta = ((1 + x * 2 / 64) % 2) - 1; + break; + case 2: // square + case 3: // random (in FT2 these two are the same) + delta = x < 32 ? 1 : -1; + break; + case 0: + default: // sine + delta = Math.sin(x * Math.PI / 32); + break; + } + return delta; +} + function eff_t1_5(ch) { // portamento + volume slide eff_t1_a(ch); eff_t1_3(ch); From 5af28d860ed9cc348cafcd7dc56cf52d502ebf18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Hillerstr=C3=B6m?= Date: Sat, 21 Nov 2015 02:26:50 +0100 Subject: [PATCH 03/10] Update vibratopos according to the spec --- xmeffects.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/xmeffects.js b/xmeffects.js index dad153d..7249bc7 100644 --- a/xmeffects.js +++ b/xmeffects.js @@ -71,8 +71,11 @@ function eff_t1_4(ch) { // vibrato ch.vibratopos, ch.vibratospeed, ch.vibratodepth); ch.periodoffset = 0; } - ch.vibratopos += ch.vibratospeed; - ch.vibratopos &= 63; + // only updates on non-first ticks + if (player.cur_tick > 0) { + ch.vibratopos += ch.vibratospeed; + ch.vibratopos &= 63; + } } function getVibratoDelta(type, x) { From 413bc4b5387c4ef451b70ccabc6f557d7f8d5a5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Hillerstr=C3=B6m?= Date: Sat, 21 Nov 2015 02:30:04 +0100 Subject: [PATCH 04/10] Retrigger waveforms 0-3 --- xm.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/xm.js b/xm.js index 6af8432..9a02f5c 100644 --- a/xm.js +++ b/xm.js @@ -264,6 +264,10 @@ function nextRow() { if (ch.note) { ch.period = periodForNote(ch, ch.note); } + // waveforms 0-3 are retriggered on new notes while 4-7 are continuous + if (ch.vibratotype < 4) { + ch.vibratopos = 0; + } } } } From b81d675b660262fd0c247bdf1bd24b7fe459ffc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Hillerstr=C3=B6m?= Date: Sat, 21 Nov 2015 15:50:48 +0100 Subject: [PATCH 05/10] Test for resetting vibrato pos on note retrigger --- test/instrument.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/instrument.js b/test/instrument.js index 5bf1948..433b2a4 100644 --- a/test/instrument.js +++ b/test/instrument.js @@ -46,10 +46,12 @@ exports['test note trigger'] = function(assert) { XMPlayer.nextRow(); ch.pan = 1; // forcibly override panning ch.off = 100; // and sample offset + ch.vibratopos = 1; // and vibrato position 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'); + assert.equal(ch.vibratopos, 0, 'set vibrato pos=0'); }; From e39f601038d75e5d4abc7b84e5422798bc0dcc6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Hillerstr=C3=B6m?= Date: Sat, 21 Nov 2015 15:50:58 +0100 Subject: [PATCH 06/10] Double vibrato depth to act like FT2 --- xmeffects.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xmeffects.js b/xmeffects.js index 7249bc7..27e906c 100644 --- a/xmeffects.js +++ b/xmeffects.js @@ -56,7 +56,7 @@ function eff_t1_3(ch) { // portamento function eff_t0_4(ch, data) { // vibrato if (data & 0x0f) { - ch.vibratodepth = data & 0x0f; + ch.vibratodepth = (data & 0x0f) * 2; } if (data >> 4) { ch.vibratospeed = data >> 4; From 677c157c715f7a6b1bc409de59af0e2bc5a1057a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Hillerstr=C3=B6m?= Date: Sat, 21 Nov 2015 19:54:54 +0100 Subject: [PATCH 07/10] Fix failing vibrato test --- test/effects.js | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/test/effects.js b/test/effects.js index b64f8a2..6b46303 100644 --- a/test/effects.js +++ b/test/effects.js @@ -85,7 +85,7 @@ exports['test 3xx portamento'] = function(assert) { assert.equal(ch.period, 1152 - 16, 'row 1 tick 2 period -16'); }; -exports['test 4xy vibrato'] = function(assert) { +exports['test 4xy vibrato - sine'] = function(assert) { var xm = testdata.resetXMData(); // vibrato 4xy: speed x, depth y // full cycle is 64/speed @@ -107,37 +107,37 @@ exports['test 4xy vibrato'] = function(assert) { XMPlayer.nextTick(); // row 0 tick 1 // compute logical period p from actual play frequency var p = 16*12 * Math.log(p0 / ch.doff) / Math.log(2); - assert.equal(p.toFixed(3), "0.707", 'row 0 tick 1 period +0.707'); + assert.equal(p.toFixed(3), "0.000", 'row 0 tick 1 period +0'); XMPlayer.nextTick(); // row 0 tick 2 p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); - assert.equal(p.toFixed(3), "1.000", 'row 0 tick 2 period +1.000'); + assert.equal(p.toFixed(3), "1.414", 'row 0 tick 2 period +1.414'); XMPlayer.nextTick(); // row 1 tick 0 p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); - assert.equal(p.toFixed(3), "1.414", 'row 1 tick 0 period +1.414'); + assert.equal(p.toFixed(3), "4.000", 'row 1 tick 0 period +4.000'); XMPlayer.nextTick(); // row 1 tick 1 p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); - assert.equal(p.toFixed(3), "0.000", 'row 1 tick 1 period +0'); + assert.equal(p.toFixed(3), "4.000", 'row 1 tick 1 period +4.000'); XMPlayer.nextTick(); // row 1 tick 2 p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); - assert.equal(p.toFixed(3), "-1.414", 'row 1 tick 2 period -1.414'); + assert.equal(p.toFixed(3), "2.828", 'row 1 tick 2 period 2.828'); XMPlayer.nextTick(); // row 2 tick 0 p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); - assert.equal(p.toFixed(3), "-2.000", 'row 2 tick 0 period -2.000'); + assert.equal(p.toFixed(3), "0.000", 'row 2 tick 0 period +0'); XMPlayer.nextTick(); // row 2 tick 1 p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); - assert.equal(p.toFixed(3), "-1.990", 'row 2 tick 1 period -1.990'); + assert.equal(p.toFixed(3), "0.000", 'row 2 tick 1 period +0'); XMPlayer.nextTick(); // row 2 tick 2 p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); - assert.equal(p.toFixed(3), "-1.962", 'row 2 tick 2 period -1.962'); + assert.equal(p.toFixed(3), "-0.392", 'row 2 tick 2 period -0.392'); XMPlayer.nextTick(); // row 3 tick 0 p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); - assert.equal(p.toFixed(3), "-1.914", 'row 3 tick 0 period -1.914'); + assert.equal(p.toFixed(3), "-0.780", 'row 3 tick 0 period -0.780'); XMPlayer.nextTick(); // row 3 tick 1 p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); - assert.equal(p.toFixed(3), "-1.848", 'row 3 tick 1 period -1.848'); + assert.equal(p.toFixed(3), "-0.780", 'row 3 tick 1 period -0.780'); XMPlayer.nextTick(); // row 3 tick 2 p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); - assert.equal(p.toFixed(3), "-1.764", 'row 3 tick 2 period -1.764'); + assert.equal(p.toFixed(3), "-1.161", 'row 3 tick 2 period -1.161'); XMPlayer.nextTick(); // row 4 tick 0 p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); assert.equal(p.toFixed(3), "0.000", 'row 4 tick 0 period 0 - no vibrato'); @@ -148,16 +148,16 @@ exports['test 4xy vibrato'] = function(assert) { // that's what I'm assuming here... XMPlayer.nextTick(); // row 5 tick 0 p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); - assert.equal(p.toFixed(3), "-1.663", 'row 5 tick 0 period -1.663 - vibrato resume'); + assert.equal(p.toFixed(3), "-1.531", 'row 5 tick 0 period -1.531 - vibrato resume'); XMPlayer.nextTick(); // row 5 tick 1 p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); - assert.equal(p.toFixed(3), "-1.546", 'row 5 tick 1 period -1.546'); + assert.equal(p.toFixed(3), "-1.531", 'row 5 tick 1 period -1.531'); XMPlayer.nextTick(); // row 5 tick 2 p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); - assert.equal(p.toFixed(3), "-1.414", 'row 5 tick 2 period -1.414'); + assert.equal(p.toFixed(3), "-1.886", 'row 5 tick 2 period -1.886'); XMPlayer.nextTick(); // row 6 tick 0 p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); - assert.equal(p.toFixed(3), "-1.269", 'row 6 tick 0 period -1.269'); + assert.equal(p.toFixed(3), "-1.111", 'row 6 tick 0 period -1.111'); }; exports['test Axy volume slide'] = function(assert) { From 9b959532fb513f31a9fcfb3256dcdb7e056f62cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Hillerstr=C3=B6m?= Date: Sat, 21 Nov 2015 20:19:30 +0100 Subject: [PATCH 08/10] Add tests for E4x, E41 and E42 --- test/effects.js | 159 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) diff --git a/test/effects.js b/test/effects.js index 6b46303..4a84f07 100644 --- a/test/effects.js +++ b/test/effects.js @@ -160,6 +160,143 @@ exports['test 4xy vibrato - sine'] = function(assert) { assert.equal(p.toFixed(3), "-1.111", 'row 6 tick 0 period -1.111'); }; +exports['test 4xy vibrato - saw'] = function(assert) { + var xm = testdata.resetXMData(); + // vibrato 4xy: speed x, depth y + // full cycle is 64/speed + xm.patterns[0] = [ + [[48, 1, -1, 14, 0x41]], // C-4 1 -- E41 - 1 = saw (ramp-down) + [[-1, -1, -1, 4, 0x81]], // --- -- -- 481 + [[-1, -1, -1, 4, 0x00]], // --- -- -- 400 + [[-1, -1, -1, 0, 0x00]], // --- -- -- --- - no vibrato + [[-1, -1, -1, 4, 0x00]], // --- -- -- 400 - resume vibrato @ pos 0 + ]; + XMPlayer.xm.tempo = 4; + var ch = xm.channelinfo[0]; + assert.equal(ch.vibratotype, 0, 'initial vibratotype 0'); + XMPlayer.nextTick(); // row 0 tick 0 + var p0 = ch.doff; + assert.equal(ch.vibratotype, 1, 'row 0 tick 0 vibratotype=1'); + XMPlayer.nextTick(); // row 0 tick 1 + XMPlayer.nextTick(); // row 0 tick 2 + XMPlayer.nextTick(); // row 0 tick 3 + XMPlayer.nextTick(); // row 1 tick 0 + assert.equal(ch.periodoffset, 0, 'row 1 tick 0 periodoffset=0'); + XMPlayer.nextTick(); // row 1 tick 1 + // compute logical period p from actual play frequency + var p = 16*12 * Math.log(p0 / ch.doff) / Math.log(2); + assert.equal(p.toFixed(3), "0.000", 'row 1 tick 1 period +0'); + XMPlayer.nextTick(); // row 1 tick 2 + p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); + assert.equal(p.toFixed(3), "0.500", 'row 1 tick 2 period +0.500'); + XMPlayer.nextTick(); // row 1 tick 3 + p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); + assert.equal(p.toFixed(3), "1.000", 'row 1 tick 3 period +1.000'); + XMPlayer.nextTick(); // row 2 tick 0 + p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); + assert.equal(p.toFixed(3), "1.500", 'row 2 tick 0 period +1.500'); + XMPlayer.nextTick(); // row 2 tick 1 + p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); + assert.equal(p.toFixed(3), "1.500", 'row 2 tick 1 period +1.500'); + XMPlayer.nextTick(); // row 2 tick 2 + p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); + assert.equal(p.toFixed(3), "-2.000", 'row 2 tick 2 period -2.000'); + XMPlayer.nextTick(); // row 2 tick 3 + p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); + assert.equal(p.toFixed(3), "-1.500", 'row 2 tick 3 period -1.500'); + XMPlayer.nextTick(); // row 3 tick 0 + p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); + assert.equal(p.toFixed(3), "0.000", 'row 3 tick 0 period 0 - no vibrato'); + XMPlayer.nextTick(); // row 3 tick 1 + XMPlayer.nextTick(); // row 3 tick 2 + XMPlayer.nextTick(); // row 3 tick 3 + XMPlayer.nextTick(); // row 4 tick 0 + p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); + assert.equal(p.toFixed(3), "-1.000", 'row 4 tick 0 period -1.000 - vibrato resume'); + XMPlayer.nextTick(); // row 4 tick 1 + p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); + assert.equal(p.toFixed(3), "-1.000", 'row 4 tick 1 period -1.000'); + XMPlayer.nextTick(); // row 4 tick 2 + p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); + assert.equal(p.toFixed(3), "-0.500", 'row 4 tick 2 period -0.500'); + XMPlayer.nextTick(); // row 4 tick 3 + p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); + assert.equal(p.toFixed(3), "0.000", 'row 4 tick 3 period +0'); +}; + +exports['test 4xy vibrato - square'] = function(assert) { + var xm = testdata.resetXMData(); + // vibrato 4xy: speed x, depth y + // full cycle is 64/speed + xm.patterns[0] = [ + [[48, 1, -1, 14, 0x42]], // C-4 1 -- E42 - 2 = square + [[-1, -1, -1, 4, 0x81]], // --- -- -- 481 + [[-1, -1, -1, 4, 0x02]], // --- -- -- 402 + [[-1, -1, -1, 4, 0x10]], // --- -- -- 410 + [[-1, -1, -1, 4, 0x03]], // --- -- -- 403 + [[-1, -1, -1, 0, 0x00]], // --- -- -- --- - no vibrato + [[-1, -1, -1, 4, 0x00]], // --- -- -- 400 - resume vibrato @ pos 0 + ]; + XMPlayer.xm.tempo = 3; + var ch = xm.channelinfo[0]; + assert.equal(ch.vibratotype, 0, 'initial vibratotype 0'); + XMPlayer.nextTick(); // row 0 tick 0 + var p0 = ch.doff; + assert.equal(ch.vibratotype, 2, 'row 0 tick 0 vibratotype=2'); + XMPlayer.nextTick(); // row 0 tick 1 + XMPlayer.nextTick(); // row 0 tick 2 + XMPlayer.nextTick(); // row 1 tick 0 + assert.equal(ch.periodoffset, 2, 'row 1 tick 0 periodoffset=2'); + XMPlayer.nextTick(); // row 1 tick 1 + // compute logical period p from actual play frequency + var p = 16*12 * Math.log(p0 / ch.doff) / Math.log(2); + assert.equal(p.toFixed(3), "2.000", 'row 1 tick 1 period +2.000'); + XMPlayer.nextTick(); // row 1 tick 2 + p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); + assert.equal(p.toFixed(3), "2.000", 'row 1 tick 2 period +2.000'); + XMPlayer.nextTick(); // row 2 tick 0 + p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); + assert.equal(p.toFixed(3), "4.000", 'row 2 tick 0 period +4.000'); + XMPlayer.nextTick(); // row 2 tick 1 + p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); + assert.equal(p.toFixed(3), "4.000", 'row 2 tick 1 period +4.000'); + XMPlayer.nextTick(); // row 2 tick 2 + p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); + assert.equal(p.toFixed(3), "4.000", 'row 2 tick 2 period +4.000'); + XMPlayer.nextTick(); // row 3 tick 0 + p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); + assert.equal(p.toFixed(3), "-4.000", 'row 3 tick 0 period -4.000'); + XMPlayer.nextTick(); // row 3 tick 1 + p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); + assert.equal(p.toFixed(3), "-4.000", 'row 3 tick 1 period -4.000'); + XMPlayer.nextTick(); // row 3 tick 2 + p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); + assert.equal(p.toFixed(3), "-4.000", 'row 3 tick 2 period -4.000'); + XMPlayer.nextTick(); // row 4 tick 0 + p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); + assert.equal(p.toFixed(3), "-6.000", 'row 4 tick 0 period -6.000'); + XMPlayer.nextTick(); // row 4 tick 1 + p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); + assert.equal(p.toFixed(3), "-6.000", 'row 4 tick 1 period -6.000'); + XMPlayer.nextTick(); // row 4 tick 2 + p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); + assert.equal(p.toFixed(3), "-6.000", 'row 4 tick 2 period -6.000'); + XMPlayer.nextTick(); // row 4 tick 0 + p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); + assert.equal(p.toFixed(3), "0.000", 'row 4 tick 0 period 0 - no vibrato'); + XMPlayer.nextTick(); // row 4 tick 1 + XMPlayer.nextTick(); // row 4 tick 2 + XMPlayer.nextTick(); // row 5 tick 0 + p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); + assert.equal(p.toFixed(3), "-6.000", 'row 5 tick 0 period -6.000 - vibrato resume'); + XMPlayer.nextTick(); // row 5 tick 1 + p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); + assert.equal(p.toFixed(3), "-6.000", 'row 5 tick 1 period -6.000'); + XMPlayer.nextTick(); // row 5 tick 2 + p = -16*12 * Math.log(ch.doff / p0) / Math.log(2); + assert.equal(p.toFixed(3), "-6.000", 'row 5 tick 2 period -6.000'); +}; + exports['test Axy volume slide'] = function(assert) { var xm = testdata.resetXMData(); XMPlayer.xm.tempo = 6; @@ -322,6 +459,28 @@ exports['test Hxy global volume slide'] = function(assert) { assert.equal(xm.global_volume, 128, 'row 3 tick 2 vol 128'); }; +exports['test E4x set vibrato waveform'] = function(assert) { + var xm = testdata.resetXMData(); + xm.patterns = [ + [ + [[48, 1, -1, 0, 0x00]], // C-4 1 -- --- (default waveform - sine) + [[48, 1, -1, 14, 0x41]], // C-4 1 -- E41 (saw, ramp-down) + [[48, 1, -1, 14, 0x42]], // C-4 1 -- E42 (square) + [[48, 1, -1, 14, 0x43]] // C-4 1 -- E43 (random) + ] + ]; + xm.tempo = 1; + var ch = xm.channelinfo[0]; + XMPlayer.nextTick(); + assert.equal(ch.vibratotype, 0, 'row 0 tick 0 vibratotype=0'); + XMPlayer.nextTick(); + assert.equal(ch.vibratotype, 1, 'row 1 tick 0 vibratotype=1'); + XMPlayer.nextTick(); + assert.equal(ch.vibratotype, 2, 'row 2 tick 0 vibratotype=2'); + XMPlayer.nextTick(); + assert.equal(ch.vibratotype, 3, 'row 3 tick 0 vibratotype=3'); +}; + exports['test E5x finetune override'] = function(assert) { var xm = testdata.resetXMData(); // set an initial finetune so we know we're overriding it... From 1d8b91c8ead4bac993a1618cc3708cc3c00654aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Hillerstr=C3=B6m?= Date: Sat, 21 Nov 2015 20:21:39 +0100 Subject: [PATCH 09/10] Remove E4x from missing effects --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index dff04a5..3c6535e 100644 --- a/index.html +++ b/index.html @@ -72,7 +72,7 @@ code: github.com/a1k0n/jsxm todo: - missing XM effects: - - E3x, E4x, E6x, E7x, E9x, EDx, EEx + - E3x, E6x, E7x, E9x, EDx, EEx - 7xy - tremolo - Kxx, Lxx, Pxy, Txy - render pattern with the wider fonts for fewer channels From e3d159e7ff1764ed56cec448401d795c20dfa609 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Hillerstr=C3=B6m?= Date: Sat, 21 Nov 2015 20:22:00 +0100 Subject: [PATCH 10/10] Add contributors to package.json --- package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 3c3e82b..e21fffb 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,10 @@ "repository": "a1k0n/jsxm", "author": "Andy Sloane (http://www.a1k0n.net/)", "license": "MIT", - + "contributors": [{ + "name": "Johan Hillerström", + "email": "progr@mmer.nu" + }], "main": "index.html", "window": { "frame": true,