UNPKG

gibberish-dsp

Version:

Gibberish is designed to be an optimized API for audio synthesis using per-sample techniques.

113 lines (109 loc) 3.3 kB
/* * https://github.com/antimatter15/heapqueue.js/blob/master/heapqueue.js * * This implementation is very loosely based off js-priority-queue * by Adam Hooper from https://github.com/adamhooper/js-priority-queue * * The js-priority-queue implementation seemed a teensy bit bloated * with its require.js dependency and multiple storage strategies * when all but one were strongly discouraged. So here is a kind of * condensed version of the functionality with only the features that * I particularly needed. * * Using it is pretty simple, you just create an instance of HeapQueue * while optionally specifying a comparator as the argument: * * var heapq = new HeapQueue(); * * //IF NEGATIVE, RETURN A * * var customq = new HeapQueue(function(a, b){ * // if b > a, return negative * // means that it spits out the smallest item first * return a - b; * }); * * Note that in this case, the default comparator is identical to * the comparator which is used explicitly in the second queue. * * Once you've initialized the heapqueue, you can plop some new * elements into the queue with the push method (vaguely reminiscent * of typical javascript arays) * * heapq.push(42); * heapq.push("kitten"); * * The push method returns the new number of elements of the queue. * * You can push anything you'd like onto the queue, so long as your * comparator function is capable of handling it. The default * comparator is really stupid so it won't be able to handle anything * other than an number by default. * * You can preview the smallest item by using peek. * * heapq.push(-9999); * heapq.peek(); // ==> -9999 * * The useful complement to to the push method is the pop method, * which returns the smallest item and then removes it from the * queue. * * heapq.push(1); * heapq.push(2); * heapq.push(3); * heapq.pop(); // ==> 1 * heapq.pop(); // ==> 2 * heapq.pop(); // ==> 3 */ const HeapQueue = function(cmp){ this.cmp = (cmp || function(a, b){ return a - b; }); this.length = 0; this.data = []; } HeapQueue.prototype.peek = function(){ return this.data[0]; }; HeapQueue.prototype.push = function(value){ this.data.push(value); var pos = this.data.length - 1, parent, x; while(pos > 0){ parent = (pos - 1) >>> 1; if(this.cmp(this.data[pos], this.data[parent]) < 0){ x = this.data[parent]; this.data[parent] = this.data[pos]; this.data[pos] = x; pos = parent; }else break; } return this.length++; }; HeapQueue.prototype.pop = function(){ var last_val = this.data.pop(), ret = this.data[0]; if(this.data.length > 0){ this.data[0] = last_val; var pos = 0, last = this.data.length - 1, left, right, minIndex, x; while(1){ left = (pos << 1) + 1; right = left + 1; minIndex = pos; if(left <= last && this.cmp(this.data[left], this.data[minIndex]) < 0) minIndex = left; if(right <= last && this.cmp(this.data[right], this.data[minIndex]) < 0) minIndex = right; if(minIndex !== pos){ x = this.data[minIndex]; this.data[minIndex] = this.data[pos]; this.data[pos] = x; pos = minIndex; }else break; } } else { ret = last_val; } this.length--; return ret; }; module.exports = HeapQueue