If you work with buffered data such as Audio/Video Frame data, you have no doubt appreciated the features of Typed Arrays that came with ES2017 javascript. The ability to move, duplicate, manipulate blocks of data using object methods is achieved by 'imposing' a dataview on the data blocks. These have made buffered data processing a breeze and fast (avoid slow for-loops and extra code ). A detailed discussion of typed arrays is found here: . javascript typed arrays The problem scenario where I took advantage of these features is this: The Problem: Receive a stream of Audio data sampled at 48000 Hz, down-sample and produce the data at 16000 Hz. The straightforward implementation is use a FIFO Queue to buffer the incoming stream, process the data in queue to produce the output. A couple of immediate challenges occurred: a. Performance: Buffers need to be processed at a rate faster than at which they arrive. b. The size of the input buffer and the size of the output are different. Implement a queue for data buffers with each piece of data in the buffer having the same datatype (Float32 for web audio data). Allow for the size of the input data buffer enqueued to be different that the size of the output buffer that is dequeued. This implementation is shown below: The Q is a large Q buffer of the correct type (Float32 in my case). A high watermark is associated with this buffer, and points to the location in the buffer where new data can be inserted during the enqueueing process. When the queue is empty, the high watermark is 0. Dequeing data off the Q is done from the 'top' (i.e. from 0) and after dequeing a block of data, the high watermark is adjusted. The solution: Here is the code (ES2017 - JavaScript). The Q is implemented as class frameBufferQB: The code: { (blobsize,readChunkSize,dataType='Float32') { (dataType != ) .log( + dataType + ); .dataStore = (blobsize); .bottom= ; .readChunkSize=readChunkSize; .blobsize=blobsize } enqueue(chunk){ ( .bottom+chunk.length > .blobsize) { .log ( + .bottom+ +chunk.length+ + .dataStore.length) } { .dataStore.set(chunk, .bottom) .bottom +=chunk.length } } dequeue() { retval= ( .bottom >= .readChunkSize) { retval= .dataStore.slice( , .readChunkSize) .dataStore.copyWithin( , .readChunkSize, .bottom) .bottom -= .readChunkSize } retval } isEmpty() { ( .bottom< .readChunkSize) } } class frameBufferQB //This class is like a queue, except that it is one large blob of float32 with a high watermark. The incoming data //is assumed to be float32Array and is accumalated into this blob at the high watermark (called bottom in code). //in blocks of chunksize and stored in a queue // Creates the data store blob constructor if 'Float32' console '**Error:' ' not implemented!' else this new Float32Array this 0 this this //This method adds the input chunk buffer to the bottom of the q data. if this this console 'blob overflow! bottom, chunklength, blobsize ' this ', ' ', ' this else this this //copy the array to the bottom this // retrieves a chunk of data of size this.readChunkSize and adjusts the bottom // If insufficient data returns false let null if this this this 0 this this 0 this this this this return return this this Example usage: myQ= frameBufferQB( , ) inpArr = ([ , , , , ]); myQ.enqueue(inpArr) .log(myQ.dequeue()) .log(myQ.dequeue()) new 100 2 //create Q with size 100 and dequeue with length of 2 new Float32Array 10 20 30 40 50 console // outputs two elements [10,20] console //outputs next two elements [30,40] Overriding enqueue/dequeue to Transform Data: To perform transformations (such as downsampling audio data, the methods enqueue and dequeue can be overridden by code to perform the transformation during these operations.