made it so you can load other xms
and as a result, fixed a ton of bugs, many many remain
This commit is contained in:
parent
66958ca7d8
commit
17123cc5f1
1 changed files with 48 additions and 19 deletions
67
xm.js
67
xm.js
|
|
@ -102,7 +102,7 @@ function next_row() {
|
||||||
// instrument trigger
|
// instrument trigger
|
||||||
if (r[i][1] != -1) {
|
if (r[i][1] != -1) {
|
||||||
var inst = instruments[r[i][1] - 1];
|
var inst = instruments[r[i][1] - 1];
|
||||||
if (inst !== undefined) {
|
if (inst != undefined) {
|
||||||
ch.inst = inst;
|
ch.inst = inst;
|
||||||
// retrigger unless overridden below
|
// retrigger unless overridden below
|
||||||
triggernote = true;
|
triggernote = true;
|
||||||
|
|
@ -121,15 +121,14 @@ function next_row() {
|
||||||
// assume linear frequency table (flags header & 1 == 1)
|
// assume linear frequency table (flags header & 1 == 1)
|
||||||
// is this true in kamel.xm?
|
// is this true in kamel.xm?
|
||||||
var inst = ch.inst;
|
var inst = ch.inst;
|
||||||
if (inst === undefined) {
|
if (inst != undefined) {
|
||||||
continue;
|
var note = r[i][0] + inst.note;
|
||||||
|
ch.note = note;
|
||||||
|
triggernote = true;
|
||||||
|
// if there's an instrument and a note, set the volume
|
||||||
|
ch.pan = inst.pan;
|
||||||
|
ch.vol = inst.vol;
|
||||||
}
|
}
|
||||||
var note = r[i][0] + inst.note;
|
|
||||||
ch.note = note;
|
|
||||||
triggernote = true;
|
|
||||||
// if there's an instrument and a note, set the volume
|
|
||||||
ch.pan = inst.pan;
|
|
||||||
ch.vol = inst.vol;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (r[i][2] != -1) { // volume column
|
if (r[i][2] != -1) { // volume column
|
||||||
|
|
@ -167,7 +166,7 @@ function next_row() {
|
||||||
ch.periodtarget = PeriodForNote(ch, ch.note);
|
ch.periodtarget = PeriodForNote(ch, ch.note);
|
||||||
}
|
}
|
||||||
triggernote = false;
|
triggernote = false;
|
||||||
if (ch.release) {
|
if (ch.release && inst != undefined) {
|
||||||
// reset envelopes if note was released but leave offset/pitch/etc
|
// reset envelopes if note was released but leave offset/pitch/etc
|
||||||
// alone
|
// alone
|
||||||
ch.envtick = 0;
|
ch.envtick = 0;
|
||||||
|
|
@ -446,6 +445,23 @@ function eff_t0_a(ch, data) { // volume slide
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function eff_t0_c(ch, data) { // set volume
|
||||||
|
ch.vol = data & 0x3f;
|
||||||
|
}
|
||||||
|
|
||||||
|
function eff_t0_f(ch, data) { // set tempo
|
||||||
|
if (data == 0) {
|
||||||
|
console.log("tempo 0?");
|
||||||
|
return;
|
||||||
|
} else if(data < 0x20) {
|
||||||
|
tempo = data;
|
||||||
|
console.log("tempo", tempo);
|
||||||
|
} else {
|
||||||
|
bpm = data;
|
||||||
|
console.log("bpm", bpm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function eff_unimplemented_t0(ch, data) {
|
function eff_unimplemented_t0(ch, data) {
|
||||||
console.log("unimplemented effect", ch.effect.toString(16), data.toString(16));
|
console.log("unimplemented effect", ch.effect.toString(16), data.toString(16));
|
||||||
}
|
}
|
||||||
|
|
@ -463,10 +479,10 @@ var effects_t0 = [ // effect functions on tick 0
|
||||||
eff_unimplemented_t0, // 9
|
eff_unimplemented_t0, // 9
|
||||||
eff_t0_a,
|
eff_t0_a,
|
||||||
eff_unimplemented_t0, // b
|
eff_unimplemented_t0, // b
|
||||||
eff_unimplemented_t0, // c
|
eff_t0_c, // c
|
||||||
eff_unimplemented_t0, // d
|
eff_unimplemented_t0, // d
|
||||||
eff_unimplemented_t0, // e
|
eff_unimplemented_t0, // e
|
||||||
eff_unimplemented_t0, // f
|
eff_t0_f, // f
|
||||||
];
|
];
|
||||||
|
|
||||||
function eff_t1_0(ch) { // arpeggio
|
function eff_t1_0(ch) { // arpeggio
|
||||||
|
|
@ -584,7 +600,9 @@ function playXM(arrayBuf) {
|
||||||
vL: 0, vR: 0, // left right volume envelope followers (changes per sample)
|
vL: 0, vR: 0, // left right volume envelope followers (changes per sample)
|
||||||
vLprev: 0, vRprev: 0,
|
vLprev: 0, vRprev: 0,
|
||||||
mute: 0,
|
mute: 0,
|
||||||
volE: 0, panE: 0
|
volE: 0, panE: 0,
|
||||||
|
vibratodepth: 1,
|
||||||
|
vibratospeed: 1,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
console.log("header len " + hlen);
|
console.log("header len " + hlen);
|
||||||
|
|
@ -608,7 +626,7 @@ function playXM(arrayBuf) {
|
||||||
var patsize = dv.getUint16(idx + 7, true);
|
var patsize = dv.getUint16(idx + 7, true);
|
||||||
console.log("pattern %d: %d bytes, %d rows", i, patsize, patrows);
|
console.log("pattern %d: %d bytes, %d rows", i, patsize, patrows);
|
||||||
idx += 9;
|
idx += 9;
|
||||||
for (var j = 0; j < patrows; j++) {
|
for (var j = 0; patsize > 0 && j < patrows; j++) {
|
||||||
row = [];
|
row = [];
|
||||||
pretty_row = [];
|
pretty_row = [];
|
||||||
for (var k = 0; k < nchan; k++) {
|
for (var k = 0; k < nchan; k++) {
|
||||||
|
|
@ -642,8 +660,6 @@ function playXM(arrayBuf) {
|
||||||
pretty_row.push(prettify_notedata(note, inst, vol, efftype, effparam));
|
pretty_row.push(prettify_notedata(note, inst, vol, efftype, effparam));
|
||||||
row.push([note, inst, vol, efftype, effparam]);
|
row.push([note, inst, vol, efftype, effparam]);
|
||||||
}
|
}
|
||||||
if (i == 12)
|
|
||||||
console.log(pretty_row.join(" "));
|
|
||||||
pattern.push(row);
|
pattern.push(row);
|
||||||
}
|
}
|
||||||
patterns.push(pattern);
|
patterns.push(pattern);
|
||||||
|
|
@ -679,6 +695,7 @@ function playXM(arrayBuf) {
|
||||||
console.log("hdrsiz %d; instrument %d: '%s' %d samples, samphdrsiz %d",
|
console.log("hdrsiz %d; instrument %d: '%s' %d samples, samphdrsiz %d",
|
||||||
hdrsiz, i, instname, nsamp, samphdrsiz);
|
hdrsiz, i, instname, nsamp, samphdrsiz);
|
||||||
idx += hdrsiz;
|
idx += hdrsiz;
|
||||||
|
var totalsamples = 0;
|
||||||
for (var j = 0; j < nsamp; j++) {
|
for (var j = 0; j < nsamp; j++) {
|
||||||
var samplen = dv.getUint32(idx, true);
|
var samplen = dv.getUint32(idx, true);
|
||||||
var samploop = dv.getUint32(idx+4, true);
|
var samploop = dv.getUint32(idx+4, true);
|
||||||
|
|
@ -698,16 +715,23 @@ function playXM(arrayBuf) {
|
||||||
env_vol_loop_start, env_vol_loop_end, "type", env_vol_type);
|
env_vol_loop_start, env_vol_loop_end, "type", env_vol_type);
|
||||||
console.log(" pan env", env_pan, env_pan_sustain,
|
console.log(" pan env", env_pan, env_pan_sustain,
|
||||||
env_pan_loop_start, env_pan_loop_end, "type", env_pan_type);
|
env_pan_loop_start, env_pan_loop_end, "type", env_pan_type);
|
||||||
idx += samplen + samphdrsiz;
|
idx += samphdrsiz;
|
||||||
|
totalsamples += samplen;
|
||||||
}
|
}
|
||||||
|
idx += totalsamples;
|
||||||
inst = {
|
inst = {
|
||||||
'name': instname,
|
'name': instname,
|
||||||
'len': samplen, 'loop': samploop,
|
'len': samplen, 'loop': samploop,
|
||||||
'looplen': samplooplen, 'note': sampnote, 'fine': sampfinetune,
|
'looplen': samplooplen, 'note': sampnote, 'fine': sampfinetune,
|
||||||
'pan': samppan, 'type': samptype, 'vol': sampvol,
|
'pan': samppan, 'type': samptype, 'vol': sampvol,
|
||||||
'fine': sampfinetune,
|
'fine': sampfinetune,
|
||||||
'sampledata': ConvertSample(new Uint8Array(arrayBuf, sampleoffset, samplen), samptype & 4),
|
'sampledata': ConvertSample(new Uint8Array(arrayBuf, sampleoffset, samplen), samptype & 16),
|
||||||
};
|
};
|
||||||
|
if (samptype & 16) {
|
||||||
|
inst.len /= 2;
|
||||||
|
inst.loop /= 2;
|
||||||
|
inst.looplen /= 2;
|
||||||
|
}
|
||||||
if (env_vol_type) {
|
if (env_vol_type) {
|
||||||
inst.env_vol = new Envelope(
|
inst.env_vol = new Envelope(
|
||||||
env_vol,
|
env_vol,
|
||||||
|
|
@ -726,6 +750,7 @@ function playXM(arrayBuf) {
|
||||||
}
|
}
|
||||||
instruments.push(inst);
|
instruments.push(inst);
|
||||||
} else {
|
} else {
|
||||||
|
idx += hdrsiz;
|
||||||
instruments.push(null);
|
instruments.push(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -746,7 +771,11 @@ function playXM(arrayBuf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var xmReq = new XMLHttpRequest();
|
var xmReq = new XMLHttpRequest();
|
||||||
xmReq.open("GET", "kamel.xm", true);
|
var uri = location.search.substr(1);
|
||||||
|
if (uri == "") {
|
||||||
|
uri = "kamel.xm";
|
||||||
|
}
|
||||||
|
xmReq.open("GET", uri, true);
|
||||||
xmReq.responseType = "arraybuffer";
|
xmReq.responseType = "arraybuffer";
|
||||||
xmReq.onload = function (xmEvent) {
|
xmReq.onload = function (xmEvent) {
|
||||||
var arrayBuffer = xmReq.response;
|
var arrayBuffer = xmReq.response;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue