added a click/pop filter on volume and note end.

sounds a LOT better now.  just needs effects!
This commit is contained in:
Andy Sloane 2015-10-23 17:58:42 -07:00
commit 6837fbb42e
2 changed files with 22 additions and 8 deletions

View file

@ -11,5 +11,7 @@ todo:
</pre> </pre>
<pre id='debug'> <pre id='debug'>
</pre> </pre>
<pre id='pattern'>
</pre>
</body> </body>

28
xm.js
View file

@ -202,11 +202,14 @@ function audio_cb(e) {
for (var j = 0; j < nchan; j++) { for (var j = 0; j < nchan; j++) {
var ch = channelinfo[j]; var ch = channelinfo[j];
var inst = ch.inst; var inst = ch.inst;
if (inst === undefined) continue; var samp, sample_end;
var samp = inst.sampledata;
var sample_end = inst.len;
var looplen = 0;
var loop = false; var loop = false;
var looplen = 0;
if (inst === undefined) {
continue;
}
samp = inst.sampledata;
sample_end = inst.len;
if ((inst.type & 3) == 1) { // todo: support pingpong if ((inst.type & 3) == 1) { // todo: support pingpong
loop = true; loop = true;
looplen = inst.looplen; looplen = inst.looplen;
@ -234,8 +237,10 @@ function audio_cb(e) {
var t = k - kk; var t = k - kk;
si = t * sj + (1 - t) * si; si = t * sj + (1 - t) * si;
*/ */
dataL[i] += Filter(volL * si, ch.filter, ch.filterstate[0]); vl = Filter(volL, ch.popfilter, ch.popfilterstate[0]);
dataR[i] += Filter(volR * si, ch.filter, ch.filterstate[1]); vr = Filter(volR, ch.popfilter, ch.popfilterstate[1]);
dataL[i] += Filter(vl * si, ch.filter, ch.filterstate[0]);
dataR[i] += Filter(vr * si, ch.filter, ch.filterstate[1]);
k += dk; k += dk;
if (k >= sample_end) { // TODO: implement pingpong looping if (k >= sample_end) { // TODO: implement pingpong looping
if (loop) { if (loop) {
@ -243,6 +248,11 @@ function audio_cb(e) {
} else { } else {
// kill sample // kill sample
ch.inst = undefined; ch.inst = undefined;
for (i++; i < offset+tickduration; i++) {
// fill rest of buffer with filtered silence to avoid a pop
dataL[i] += Filter(0, ch.popfilter, ch.filterstate[0]);
dataR[i] += Filter(0, ch.popfilter, ch.filterstate[1]);
}
break; break;
} }
} }
@ -297,7 +307,9 @@ function playXM(arrayBuf) {
bpm = dv.getUint16(0x4e, true); bpm = dv.getUint16(0x4e, true);
for (var i = 0; i < nchan; i++) { for (var i = 0; i < nchan; i++) {
channelinfo.push({ channelinfo.push({
filterstate: [new Float32Array(3), new Float32Array(3)] filterstate: [new Float32Array(3), new Float32Array(3)],
popfilter: FilterCoeffs(200.0 / 44100.0),
popfilterstate: [new Float32Array(3), new Float32Array(3)]
}) })
} }
console.log("header len " + hlen); console.log("header len " + hlen);
@ -425,7 +437,7 @@ function playXM(arrayBuf) {
audioctx = new AudioContext(); audioctx = new AudioContext();
gainNode = audioctx.createGain(); gainNode = audioctx.createGain();
gainNode.gain.value = 0.2; // master volume gainNode.gain.value = 0.1; // master volume
jsNode = audioctx.createScriptProcessor(4096, 0, 2); jsNode = audioctx.createScriptProcessor(4096, 0, 2);
jsNode.onaudioprocess = audio_cb; jsNode.onaudioprocess = audio_cb;
jsNode.connect(gainNode); jsNode.connect(gainNode);