effects 1,2,3
Change-Id: I27664eb1b7f052efa3c7dd67d69f179a419793a8
This commit is contained in:
parent
fca447528e
commit
597d9cfc6e
1 changed files with 60 additions and 22 deletions
82
xm.js
82
xm.js
|
|
@ -82,12 +82,21 @@ function Filter(x, coef, state) {
|
|||
return y;
|
||||
}
|
||||
|
||||
function UpdateChannelNote(ch, note, f_smp) {
|
||||
var freq = 8363 * Math.pow(2, note/12.0 + ch.inst.fine/(12*128.0) - 4);
|
||||
function UpdateChannelPeriod(ch, period, f_smp) {
|
||||
var freq = 8363 * Math.pow(2, (4608 - period) / 768);
|
||||
ch.doff = freq / f_smp;
|
||||
ch.filter = FilterCoeffs(ch.doff / 2);
|
||||
}
|
||||
|
||||
function PeriodForNote(ch, note) {
|
||||
return 7680 - note*64 - ch.inst.fine*0.5;
|
||||
}
|
||||
|
||||
function UpdateChannelNote(ch, note, f_smp) {
|
||||
ch.period = PeriodForNote(ch, note);
|
||||
UpdateChannelPeriod(ch, ch.period, f_smp);
|
||||
}
|
||||
|
||||
var cur_songpos = -1, cur_pat = -1, cur_row = 64, cur_ticksamp = 0;
|
||||
var cur_tick = 6;
|
||||
var patdisplay = [];
|
||||
|
|
@ -105,6 +114,7 @@ function next_row(f_smp) {
|
|||
pretty_row = [];
|
||||
for (var i = 0; i < r.length; i++) {
|
||||
var ch = channelinfo[i];
|
||||
ch.update = false;
|
||||
pretty_row.push(prettify_notedata(r[i][0], r[i][1], r[i][2], r[i][3], r[i][4]));
|
||||
// instrument trigger
|
||||
if (r[i][1] != -1) {
|
||||
|
|
@ -120,6 +130,7 @@ function next_row(f_smp) {
|
|||
// console.log("invalid inst", r[i][1], instruments.length);
|
||||
}
|
||||
}
|
||||
var triggernote = false;
|
||||
// note trigger
|
||||
if (r[i][0] != -1) {
|
||||
if (r[i][0] == 96) {
|
||||
|
|
@ -132,22 +143,12 @@ function next_row(f_smp) {
|
|||
if (inst === undefined) {
|
||||
continue;
|
||||
}
|
||||
// wtf is this?!
|
||||
// var period = 7680 - r[i][0]*64 - inst.fine*0.5;
|
||||
// var freq = 8363 * Math.pow(2, (4608 - period) / 768);
|
||||
var note = r[i][0] + inst.note;
|
||||
ch.note = note;
|
||||
ch.off = 0;
|
||||
ch.release = 0;
|
||||
ch.envtick = 0;
|
||||
UpdateChannelNote(ch, note, f_smp);
|
||||
// console.log("channel", i, r[i][0], ch);
|
||||
triggernote = true;
|
||||
// if there's an instrument and a note, set the volume
|
||||
if (r[i][0] != -1) {
|
||||
var p = (inst.pan - 128) / 128.0;
|
||||
ch.volL = Math.sqrt(1 - p) * inst.vol;
|
||||
ch.volR = Math.sqrt(1 + p) * inst.vol;
|
||||
}
|
||||
ch.pan = inst.pan;
|
||||
ch.vol = inst.vol;
|
||||
}
|
||||
}
|
||||
if (r[i][2] != -1) { // volume column
|
||||
|
|
@ -156,15 +157,33 @@ function next_row(f_smp) {
|
|||
if (v < 0x10) {
|
||||
console.log("channel", i, "invalid volume", v.toString(16));
|
||||
} else if (v <= 0x50) {
|
||||
ch.volL = v - 0x10;
|
||||
ch.volR = v - 0x10;
|
||||
ch.vol = v - 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
ch.effect = r[i][3];
|
||||
ch.effectdata = r[i][4];
|
||||
// TODO: process initial effect tick for effects which need it
|
||||
|
||||
if (ch.effect == 1 && ch.effectdata != 0) {
|
||||
ch.slideupspeed = ch.effectdata;
|
||||
}
|
||||
if (ch.effect == 2 && ch.effectdata != 0) {
|
||||
ch.slidedownspeed = ch.effectdata;
|
||||
}
|
||||
if (ch.effect == 3 || ch.effect == 5) {
|
||||
if (r[i][0] != -1)
|
||||
ch.periodtarget = PeriodForNote(ch, ch.note);
|
||||
if (ch.effect == 3 && ch.effectdata != 0) {
|
||||
ch.portaspeed = ch.effectdata;
|
||||
}
|
||||
triggernote = false;
|
||||
}
|
||||
if (triggernote) {
|
||||
ch.off = 0;
|
||||
ch.release = 0;
|
||||
ch.envtick = 0;
|
||||
UpdateChannelNote(ch, note, f_smp);
|
||||
}
|
||||
}
|
||||
var debug = document.getElementById("debug");
|
||||
debug.innerHTML = 'pat ' + cur_pat + ' row ' + (cur_row-1);
|
||||
|
|
@ -192,6 +211,22 @@ function next_tick(f_smp) {
|
|||
var note = ch.note + arpeggio[cur_tick % 3];
|
||||
UpdateChannelNote(ch, note, f_smp);
|
||||
}
|
||||
if (ch.effect == 1 && ch.slideupspeed !== undefined) {
|
||||
ch.period -= ch.slideupspeed;
|
||||
UpdateChannelPeriod(ch, ch.period, f_smp);
|
||||
}
|
||||
if (ch.effect == 2 && ch.slidedownspeed !== undefined) {
|
||||
ch.period += ch.slidedownspeed;
|
||||
UpdateChannelPeriod(ch, ch.period, f_smp);
|
||||
}
|
||||
if (ch.effect == 3 && ch.periodtarget !== undefined && ch.portaspeed !== undefined) {
|
||||
if (ch.period > ch.periodtarget) {
|
||||
ch.period = Math.max(ch.periodtarget, ch.period - ch.portaspeed);
|
||||
} else {
|
||||
ch.period = Math.min(ch.periodtarget, ch.period + ch.portaspeed);
|
||||
}
|
||||
UpdateChannelPeriod(ch, ch.period, f_smp);
|
||||
}
|
||||
if (inst === undefined) continue;
|
||||
if (inst.env_vol !== undefined) {
|
||||
ch.env_vol = GetEnvelope(inst.env_vol, ch.envtick);
|
||||
|
|
@ -244,8 +279,9 @@ function audio_cb(e) {
|
|||
}
|
||||
var samplen = inst.len;
|
||||
var env_vol = ch.env_vol / 64.0;
|
||||
var volL = env_vol * ch.volL / 64.0;
|
||||
var volR = env_vol * ch.volR / 64.0;
|
||||
var p = ch.pan - 128;
|
||||
var volL = env_vol * (128 - p) * ch.vol / 8192.0;
|
||||
var volR = env_vol * (128 + p) * ch.vol / 8192.0;
|
||||
if (volL < 0) volL = 0;
|
||||
if (volR < 0) volR = 0;
|
||||
if (volR == 0 && volL == 0)
|
||||
|
|
@ -336,7 +372,9 @@ function playXM(arrayBuf) {
|
|||
channelinfo.push({
|
||||
filterstate: [new Float32Array(3), new Float32Array(3)],
|
||||
popfilter: FilterCoeffs(200.0 / 44100.0),
|
||||
popfilterstate: [new Float32Array(3), new Float32Array(3)]
|
||||
popfilterstate: [new Float32Array(3), new Float32Array(3)],
|
||||
vol: 0,
|
||||
pan: 128
|
||||
})
|
||||
}
|
||||
console.log("header len " + hlen);
|
||||
|
|
@ -394,7 +432,7 @@ function playXM(arrayBuf) {
|
|||
pretty_row.push(prettify_notedata(note, inst, vol, efftype, effparam));
|
||||
row.push([note, inst, vol, efftype, effparam]);
|
||||
}
|
||||
if (i == 0)
|
||||
if (i == 12)
|
||||
console.log(pretty_row.join(" "));
|
||||
pattern.push(row);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue