inlined all filters
This commit is contained in:
parent
f8a278f456
commit
4a0efd648d
1 changed files with 20 additions and 21 deletions
41
xm.js
41
xm.js
|
|
@ -75,14 +75,7 @@ function FilterCoeffs(f_c) {
|
||||||
}
|
}
|
||||||
|
|
||||||
popfilter = FilterCoeffs(200.0 / 44100.0);
|
popfilter = FilterCoeffs(200.0 / 44100.0);
|
||||||
|
popfilter_alpha = 0.9837;
|
||||||
function Filter(x, coef, state) {
|
|
||||||
var y = coef[0] * (x + state[0]) + coef[1]*state[1] + coef[2]*state[2];
|
|
||||||
state[0] = x;
|
|
||||||
state[2] = state[1];
|
|
||||||
state[1] = y;
|
|
||||||
return y;
|
|
||||||
}
|
|
||||||
|
|
||||||
function UpdateChannelPeriod(ch, period, f_smp) {
|
function UpdateChannelPeriod(ch, period, f_smp) {
|
||||||
var freq = 8363 * Math.pow(2, (4608 - period) / 768);
|
var freq = 8363 * Math.pow(2, (4608 - period) / 768);
|
||||||
|
|
@ -213,15 +206,15 @@ function next_tick(f_smp) {
|
||||||
var note = ch.note + arpeggio[cur_tick % 3];
|
var note = ch.note + arpeggio[cur_tick % 3];
|
||||||
UpdateChannelNote(ch, note, f_smp);
|
UpdateChannelNote(ch, note, f_smp);
|
||||||
}
|
}
|
||||||
if (ch.effect == 1 && ch.slideupspeed !== undefined) {
|
if (ch.effect == 1 && cur_tick != 0 && ch.slideupspeed !== undefined) {
|
||||||
ch.period -= ch.slideupspeed;
|
ch.period -= ch.slideupspeed;
|
||||||
UpdateChannelPeriod(ch, ch.period, f_smp);
|
UpdateChannelPeriod(ch, ch.period, f_smp);
|
||||||
}
|
}
|
||||||
if (ch.effect == 2 && ch.slidedownspeed !== undefined) {
|
if (ch.effect == 2 && cur_tick != 0 && ch.slidedownspeed !== undefined) {
|
||||||
ch.period += ch.slidedownspeed;
|
ch.period += ch.slidedownspeed;
|
||||||
UpdateChannelPeriod(ch, ch.period, f_smp);
|
UpdateChannelPeriod(ch, ch.period, f_smp);
|
||||||
}
|
}
|
||||||
if (ch.effect == 3 && ch.periodtarget !== undefined && ch.portaspeed !== undefined) {
|
if (ch.effect == 3 && cur_tick != 0 && ch.periodtarget !== undefined && ch.portaspeed !== undefined) {
|
||||||
if (ch.period > ch.periodtarget) {
|
if (ch.period > ch.periodtarget) {
|
||||||
ch.period = Math.max(ch.periodtarget, ch.period - ch.portaspeed);
|
ch.period = Math.max(ch.periodtarget, ch.period - ch.portaspeed);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -292,12 +285,15 @@ function audio_cb(e) {
|
||||||
var dk = ch.doff;
|
var dk = ch.doff;
|
||||||
// console.log(j, offset, ch);
|
// console.log(j, offset, ch);
|
||||||
for (var i = offset; i < offset+tickduration; i++) {
|
for (var i = offset; i < offset+tickduration; i++) {
|
||||||
var si = samp[k|0];
|
var s = samp[k|0];
|
||||||
si = Filter(si, ch.filter, ch.filterstate);
|
var si = ch.filter[0] * (s + ch.filterstate[0]) + ch.filter[1]*ch.filterstate[1] + ch.filter[2]*ch.filterstate[2];
|
||||||
var vl = Filter(volL, popfilter, ch.popfilterstate[0]);
|
ch.filterstate[2] = ch.filterstate[1]; ch.filterstate[1] = si; ch.filterstate[0] = s;
|
||||||
var vr = Filter(volR, popfilter, ch.popfilterstate[1]);
|
ch.vL = popfilter_alpha * ch.vL + (1 - popfilter_alpha) * (volL + ch.vLprev) * 0.5;
|
||||||
dataL[i] += vl * si;
|
ch.vR = popfilter_alpha * ch.vR + (1 - popfilter_alpha) * (volR + ch.vRprev) * 0.5;
|
||||||
dataR[i] += vr * si;
|
ch.vLprev = volL;
|
||||||
|
ch.vRprev = volR;
|
||||||
|
dataL[i] += ch.vL * si;
|
||||||
|
dataR[i] += ch.vR * si;
|
||||||
k += dk;
|
k += dk;
|
||||||
if (k >= sample_end) { // TODO: implement pingpong looping
|
if (k >= sample_end) { // TODO: implement pingpong looping
|
||||||
if (loop) {
|
if (loop) {
|
||||||
|
|
@ -309,9 +305,10 @@ function audio_cb(e) {
|
||||||
var rampend = Math.min(offset+tickduration, i+200);
|
var rampend = Math.min(offset+tickduration, i+200);
|
||||||
for (i++; i < rampend; i++) {
|
for (i++; i < rampend; i++) {
|
||||||
// fill rest of buffer with filtered silence to avoid a pop
|
// fill rest of buffer with filtered silence to avoid a pop
|
||||||
var s = Filter(0, popfilter, ch.filterstate);
|
var si = popfilter[0] * (ch.filterstate[0]) + popfilter[1]*ch.filterstate[1] + popfilter[2]*ch.filterstate[2];
|
||||||
dataL[i] += vl * s;
|
ch.filterstate[2] = ch.filterstate[1]; ch.filterstate[1] = si; ch.filterstate[0] = 0;
|
||||||
dataR[i] += vr * s;
|
dataL[i] += ch.vL * si;
|
||||||
|
dataR[i] += ch.vR * si;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -371,7 +368,9 @@ function playXM(arrayBuf) {
|
||||||
popfilter: FilterCoeffs(200.0 / 44100.0),
|
popfilter: FilterCoeffs(200.0 / 44100.0),
|
||||||
popfilterstate: [new Float32Array(3), new Float32Array(3)],
|
popfilterstate: [new Float32Array(3), new Float32Array(3)],
|
||||||
vol: 0,
|
vol: 0,
|
||||||
pan: 128
|
pan: 128,
|
||||||
|
vL: 0, vR: 0, // left right volume envelope followers (changes per sample)
|
||||||
|
vLprev: 0, vRprev: 0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
console.log("header len " + hlen);
|
console.log("header len " + hlen);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue