793 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
		
		
			
		
	
	
			793 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
| 
								 | 
							
								(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
							 | 
						||
| 
								 | 
							
								exports.FLACDemuxer = require('./src/demuxer');
							 | 
						||
| 
								 | 
							
								exports.FLACDecoder = require('./src/decoder');
							 | 
						||
| 
								 | 
							
								require('./src/ogg');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								},{"./src/decoder":2,"./src/demuxer":3,"./src/ogg":4}],2:[function(require,module,exports){
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * FLAC.js - Free Lossless Audio Codec decoder in JavaScript
							 | 
						||
| 
								 | 
							
								 * Original C version from FFmpeg (c) 2003 Alex Beregszaszi
							 | 
						||
| 
								 | 
							
								 * JavaScript port by Devon Govett and Jens Nockert of Official.fm Labs
							 | 
						||
| 
								 | 
							
								 * 
							 | 
						||
| 
								 | 
							
								 * Licensed under the same terms as the original.  The original
							 | 
						||
| 
								 | 
							
								 * license follows.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * FLAC.js is free software; you can redistribute it and/or
							 | 
						||
| 
								 | 
							
								 * modify it under the terms of the GNU Lesser General Public
							 | 
						||
| 
								 | 
							
								 * License as published by the Free Software Foundation; either
							 | 
						||
| 
								 | 
							
								 * version 2.1 of the License, or (at your option) any later version.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * FLAC.js is distributed in the hope that it will be useful,
							 | 
						||
| 
								 | 
							
								 * but WITHOUT ANY WARRANTY; without even the implied warranty of
							 | 
						||
| 
								 | 
							
								 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
							 | 
						||
| 
								 | 
							
								 * Lesser General Public License for more details.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var AV = (window.AV);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var FLACDecoder = AV.Decoder.extend(function() {
							 | 
						||
| 
								 | 
							
								    AV.Decoder.register('flac', this);
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    this.prototype.setCookie = function(cookie) {
							 | 
						||
| 
								 | 
							
								        this.cookie = cookie;
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        // initialize arrays
							 | 
						||
| 
								 | 
							
								        this.decoded = [];
							 | 
						||
| 
								 | 
							
								        for (var i = 0; i < this.format.channelsPerFrame; i++) {
							 | 
						||
| 
								 | 
							
								            this.decoded[i] = new Int32Array(cookie.maxBlockSize);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        // for 24 bit lpc frames, this is used to simulate a 64 bit int
							 | 
						||
| 
								 | 
							
								        this.lpc_total = new Int32Array(2);
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    const BLOCK_SIZES = new Int16Array([
							 | 
						||
| 
								 | 
							
								               0,      192, 576 << 0, 576 << 1, 576 << 2, 576 << 3,        0,        0,
							 | 
						||
| 
								 | 
							
								        256 << 0, 256 << 1, 256 << 2, 256 << 3, 256 << 4, 256 << 5, 256 << 6, 256 << 7
							 | 
						||
| 
								 | 
							
								    ]);
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    const SAMPLE_RATES = new Int32Array([
							 | 
						||
| 
								 | 
							
								        0, 88200, 176400, 192000,
							 | 
						||
| 
								 | 
							
								        8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000,
							 | 
						||
| 
								 | 
							
								        0, 0, 0, 0
							 | 
						||
| 
								 | 
							
								    ]);
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    const SAMPLE_SIZES = new Int8Array([
							 | 
						||
| 
								 | 
							
								        0, 8, 12, 0, 16, 20, 24, 0
							 | 
						||
| 
								 | 
							
								    ]);
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    const MAX_CHANNELS = 8,
							 | 
						||
| 
								 | 
							
								          CHMODE_INDEPENDENT = 0,
							 | 
						||
| 
								 | 
							
								          CHMODE_LEFT_SIDE = 8,
							 | 
						||
| 
								 | 
							
								          CHMODE_RIGHT_SIDE = 9,
							 | 
						||
| 
								 | 
							
								          CHMODE_MID_SIDE = 10;
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    this.prototype.readChunk = function() {
							 | 
						||
| 
								 | 
							
								        var stream = this.bitstream;
							 | 
						||
| 
								 | 
							
								        if (!stream.available(32))
							 | 
						||
| 
								 | 
							
								            return;
							 | 
						||
| 
								 | 
							
								                            
							 | 
						||
| 
								 | 
							
								        // frame sync code
							 | 
						||
| 
								 | 
							
								        if ((stream.read(15) & 0x7FFF) !== 0x7FFC)
							 | 
						||
| 
								 | 
							
								            throw new Error('Invalid sync code');
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								        var isVarSize = stream.read(1),  // variable block size stream code
							 | 
						||
| 
								 | 
							
								            bsCode = stream.read(4),  // block size
							 | 
						||
| 
								 | 
							
								            srCode = stream.read(4),  // sample rate code
							 | 
						||
| 
								 | 
							
								            chMode = stream.read(4),  // channel mode
							 | 
						||
| 
								 | 
							
								            bpsCode = stream.read(3); // bits per sample
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								        stream.advance(1); // reserved bit
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        // channels
							 | 
						||
| 
								 | 
							
								        this.chMode = chMode;
							 | 
						||
| 
								 | 
							
								        var channels;
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        if (chMode < MAX_CHANNELS) {
							 | 
						||
| 
								 | 
							
								            channels = chMode + 1;
							 | 
						||
| 
								 | 
							
								            this.chMode = CHMODE_INDEPENDENT;
							 | 
						||
| 
								 | 
							
								        } else if (chMode <= CHMODE_MID_SIDE) {
							 | 
						||
| 
								 | 
							
								            channels = 2;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            throw new Error('Invalid channel mode');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        if (channels !== this.format.channelsPerFrame)
							 | 
						||
| 
								 | 
							
								            throw new Error('Switching channel layout mid-stream not supported.');
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        // bits per sample    
							 | 
						||
| 
								 | 
							
								        if (bpsCode === 3 || bpsCode === 7)
							 | 
						||
| 
								 | 
							
								            throw new Error('Invalid sample size code');
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								        this.bps = SAMPLE_SIZES[bpsCode];
							 | 
						||
| 
								 | 
							
								        if (this.bps !== this.format.bitsPerChannel)
							 | 
						||
| 
								 | 
							
								            throw new Error('Switching bits per sample mid-stream not supported.');
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        // sample number or frame number
							 | 
						||
| 
								 | 
							
								        // see http://www.hydrogenaudio.org/forums/index.php?s=ea7085ffe6d57132c36e6105c0d434c9&showtopic=88390&pid=754269&st=0&#entry754269
							 | 
						||
| 
								 | 
							
								        var ones = 0;
							 | 
						||
| 
								 | 
							
								        while (stream.read(1) === 1)
							 | 
						||
| 
								 | 
							
								            ones++;
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        var frame_or_sample_num = stream.read(7 - ones);
							 | 
						||
| 
								 | 
							
								        for (; ones > 1; ones--) {
							 | 
						||
| 
								 | 
							
								            stream.advance(2); // == 2
							 | 
						||
| 
								 | 
							
								            frame_or_sample_num = (frame_or_sample_num << 6) | stream.read(6);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								        // block size
							 | 
						||
| 
								 | 
							
								        if (bsCode === 0)
							 | 
						||
| 
								 | 
							
								            throw new Error('Reserved blocksize code');
							 | 
						||
| 
								 | 
							
								        else if (bsCode === 6)
							 | 
						||
| 
								 | 
							
								            this.blockSize = stream.read(8) + 1;
							 | 
						||
| 
								 | 
							
								        else if (bsCode === 7)
							 | 
						||
| 
								 | 
							
								            this.blockSize = stream.read(16) + 1;
							 | 
						||
| 
								 | 
							
								        else
							 | 
						||
| 
								 | 
							
								            this.blockSize = BLOCK_SIZES[bsCode];
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								        // sample rate
							 | 
						||
| 
								 | 
							
								        var sampleRate;
							 | 
						||
| 
								 | 
							
								        if (srCode < 12)
							 | 
						||
| 
								 | 
							
								            sampleRate = SAMPLE_RATES[srCode];
							 | 
						||
| 
								 | 
							
								        else if (srCode === 12)
							 | 
						||
| 
								 | 
							
								            sampleRate = stream.read(8) * 1000;
							 | 
						||
| 
								 | 
							
								        else if (srCode === 13)
							 | 
						||
| 
								 | 
							
								            sampleRate = stream.read(16);
							 | 
						||
| 
								 | 
							
								        else if (srCode === 14)
							 | 
						||
| 
								 | 
							
								            sampleRate = stream.read(16) * 10;
							 | 
						||
| 
								 | 
							
								        else
							 | 
						||
| 
								 | 
							
								            throw new Error('Invalid sample rate code');
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								        stream.advance(8); // skip CRC check
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        // subframes
							 | 
						||
| 
								 | 
							
								        for (var i = 0; i < channels; i++)
							 | 
						||
| 
								 | 
							
								            this.decodeSubframe(i);
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        stream.align();
							 | 
						||
| 
								 | 
							
								        stream.advance(16); // skip CRC frame footer
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        var is32 = this.bps > 16,
							 | 
						||
| 
								 | 
							
								            output = new ArrayBuffer(this.blockSize * channels * (is32 ? 4 : 2)),
							 | 
						||
| 
								 | 
							
								            buf = is32 ? new Int32Array(output) : new Int16Array(output),
							 | 
						||
| 
								 | 
							
								            blockSize = this.blockSize,
							 | 
						||
| 
								 | 
							
								            decoded = this.decoded,
							 | 
						||
| 
								 | 
							
								            j = 0;
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								        switch (this.chMode) {
							 | 
						||
| 
								 | 
							
								            case CHMODE_INDEPENDENT:
							 | 
						||
| 
								 | 
							
								                for (var k = 0; k < blockSize; k++) {
							 | 
						||
| 
								 | 
							
								                    for (var i = 0; i < channels; i++) {
							 | 
						||
| 
								 | 
							
								                        buf[j++] = decoded[i][k];
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								            case CHMODE_LEFT_SIDE:
							 | 
						||
| 
								 | 
							
								                for (var i = 0; i < blockSize; i++) {
							 | 
						||
| 
								 | 
							
								                    var left = decoded[0][i],
							 | 
						||
| 
								 | 
							
								                        right = decoded[1][i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    buf[j++] = left;
							 | 
						||
| 
								 | 
							
								                    buf[j++] = (left - right);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								            case CHMODE_RIGHT_SIDE:
							 | 
						||
| 
								 | 
							
								                for (var i = 0; i < blockSize; i++) {
							 | 
						||
| 
								 | 
							
								                    var left = decoded[0][i],
							 | 
						||
| 
								 | 
							
								                        right = decoded[1][i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    buf[j++] = (left + right);
							 | 
						||
| 
								 | 
							
								                    buf[j++] = right;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								            case CHMODE_MID_SIDE:
							 | 
						||
| 
								 | 
							
								                for (var i = 0; i < blockSize; i++) {
							 | 
						||
| 
								 | 
							
								                    var left = decoded[0][i],
							 | 
						||
| 
								 | 
							
								                        right = decoded[1][i];
							 | 
						||
| 
								 | 
							
								                    
							 | 
						||
| 
								 | 
							
								                    left -= right >> 1;
							 | 
						||
| 
								 | 
							
								                    buf[j++] = (left + right);
							 | 
						||
| 
								 | 
							
								                    buf[j++] = left;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        return buf;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    this.prototype.decodeSubframe = function(channel) {
							 | 
						||
| 
								 | 
							
								        var wasted = 0,
							 | 
						||
| 
								 | 
							
								            stream = this.bitstream,
							 | 
						||
| 
								 | 
							
								            blockSize = this.blockSize,
							 | 
						||
| 
								 | 
							
								            decoded = this.decoded;
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        this.curr_bps = this.bps;
							 | 
						||
| 
								 | 
							
								        if (channel === 0) {
							 | 
						||
| 
								 | 
							
								            if (this.chMode === CHMODE_RIGHT_SIDE)
							 | 
						||
| 
								 | 
							
								                this.curr_bps++;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            if (this.chMode === CHMODE_LEFT_SIDE || this.chMode === CHMODE_MID_SIDE)
							 | 
						||
| 
								 | 
							
								                this.curr_bps++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        if (stream.read(1))
							 | 
						||
| 
								 | 
							
								            throw new Error("Invalid subframe padding");
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        var type = stream.read(6);
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        if (stream.read(1)) {
							 | 
						||
| 
								 | 
							
								            wasted = 1;
							 | 
						||
| 
								 | 
							
								            while (!stream.read(1))
							 | 
						||
| 
								 | 
							
								                wasted++;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            this.curr_bps -= wasted;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        if (this.curr_bps > 32)
							 | 
						||
| 
								 | 
							
								            throw new Error("decorrelated bit depth > 32 (" + this.curr_bps + ")");
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        if (type === 0) {
							 | 
						||
| 
								 | 
							
								            var tmp = stream.read(this.curr_bps, true);
							 | 
						||
| 
								 | 
							
								            for (var i = 0; i < blockSize; i++)
							 | 
						||
| 
								 | 
							
								                decoded[channel][i] = tmp;
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								        } else if (type === 1) {
							 | 
						||
| 
								 | 
							
								            var bps = this.curr_bps;
							 | 
						||
| 
								 | 
							
								            for (var i = 0; i < blockSize; i++)
							 | 
						||
| 
								 | 
							
								                decoded[channel][i] = stream.read(bps, true);
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								        } else if ((type >= 8) && (type <= 12)) {
							 | 
						||
| 
								 | 
							
								            this.decode_subframe_fixed(channel, type & ~0x8);
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								        } else if (type >= 32) {
							 | 
						||
| 
								 | 
							
								            this.decode_subframe_lpc(channel, (type & ~0x20) + 1);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            throw new Error("Invalid coding type");
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        if (wasted) {
							 | 
						||
| 
								 | 
							
								            for (var i = 0; i < blockSize; i++)
							 | 
						||
| 
								 | 
							
								                decoded[channel][i] <<= wasted;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    this.prototype.decode_subframe_fixed = function(channel, predictor_order) {
							 | 
						||
| 
								 | 
							
								        var decoded = this.decoded[channel],
							 | 
						||
| 
								 | 
							
								            stream = this.bitstream,
							 | 
						||
| 
								 | 
							
								            bps = this.curr_bps;
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								        // warm up samples
							 | 
						||
| 
								 | 
							
								        for (var i = 0; i < predictor_order; i++)
							 | 
						||
| 
								 | 
							
								            decoded[i] = stream.read(bps, true);
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								        this.decode_residuals(channel, predictor_order);
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        var a = 0, b = 0, c = 0, d = 0;
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        if (predictor_order > 0) 
							 | 
						||
| 
								 | 
							
								            a = decoded[predictor_order - 1];
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        if (predictor_order > 1)
							 | 
						||
| 
								 | 
							
								            b = a - decoded[predictor_order - 2];
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        if (predictor_order > 2) 
							 | 
						||
| 
								 | 
							
								            c = b - decoded[predictor_order - 2] + decoded[predictor_order - 3];
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        if (predictor_order > 3)
							 | 
						||
| 
								 | 
							
								            d = c - decoded[predictor_order - 2] + 2 * decoded[predictor_order - 3] - decoded[predictor_order - 4];
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								        switch (predictor_order) {
							 | 
						||
| 
								 | 
							
								            case 0:
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								            case 1:
							 | 
						||
| 
								 | 
							
								            case 2:
							 | 
						||
| 
								 | 
							
								            case 3:
							 | 
						||
| 
								 | 
							
								            case 4:
							 | 
						||
| 
								 | 
							
								                var abcd = new Int32Array([a, b, c, d]),
							 | 
						||
| 
								 | 
							
								                    blockSize = this.blockSize;
							 | 
						||
| 
								 | 
							
								                    
							 | 
						||
| 
								 | 
							
								                for (var i = predictor_order; i < blockSize; i++) {
							 | 
						||
| 
								 | 
							
								                    abcd[predictor_order - 1] += decoded[i];
							 | 
						||
| 
								 | 
							
								                    
							 | 
						||
| 
								 | 
							
								                    for (var j = predictor_order - 2; j >= 0; j--) {
							 | 
						||
| 
								 | 
							
								                        abcd[j] += abcd[j + 1];
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    
							 | 
						||
| 
								 | 
							
								                    decoded[i] = abcd[0];
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								            default:
							 | 
						||
| 
								 | 
							
								                throw new Error("Invalid Predictor Order " + predictor_order);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    this.prototype.decode_subframe_lpc = function(channel, predictor_order) {
							 | 
						||
| 
								 | 
							
								        var stream = this.bitstream,
							 | 
						||
| 
								 | 
							
								            decoded = this.decoded[channel],
							 | 
						||
| 
								 | 
							
								            bps = this.curr_bps,
							 | 
						||
| 
								 | 
							
								            blockSize = this.blockSize;
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								        // warm up samples
							 | 
						||
| 
								 | 
							
								        for (var i = 0; i < predictor_order; i++) {
							 | 
						||
| 
								 | 
							
								            decoded[i] = stream.read(bps, true);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var coeff_prec = stream.read(4) + 1;
							 | 
						||
| 
								 | 
							
								        if (coeff_prec === 16)
							 | 
						||
| 
								 | 
							
								            throw new Error("Invalid coefficient precision");
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        var qlevel = stream.read(5, true);
							 | 
						||
| 
								 | 
							
								        if (qlevel < 0)
							 | 
						||
| 
								 | 
							
								            throw new Error("Negative qlevel, maybe buggy stream");
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        var coeffs = new Int32Array(32);
							 | 
						||
| 
								 | 
							
								        for (var i = 0; i < predictor_order; i++) {
							 | 
						||
| 
								 | 
							
								            coeffs[i] = stream.read(coeff_prec, true);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        this.decode_residuals(channel, predictor_order);
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        if (this.bps <= 16) {
							 | 
						||
| 
								 | 
							
								            for (var i = predictor_order; i < blockSize - 1; i += 2) {
							 | 
						||
| 
								 | 
							
								                var d = decoded[i - predictor_order],
							 | 
						||
| 
								 | 
							
								                    s0 = 0, s1 = 0, c = 0;
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								                for (var j = predictor_order - 1; j > 0; j--) {
							 | 
						||
| 
								 | 
							
								                    c = coeffs[j];
							 | 
						||
| 
								 | 
							
								                    s0 += c * d;
							 | 
						||
| 
								 | 
							
								                    d = decoded[i - j];
							 | 
						||
| 
								 | 
							
								                    s1 += c * d;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								                c = coeffs[0];
							 | 
						||
| 
								 | 
							
								                s0 += c * d;
							 | 
						||
| 
								 | 
							
								                d = decoded[i] += (s0 >> qlevel);
							 | 
						||
| 
								 | 
							
								                s1 += c * d;
							 | 
						||
| 
								 | 
							
								                decoded[i + 1] += (s1 >> qlevel);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								            if (i < blockSize) {
							 | 
						||
| 
								 | 
							
								                var sum = 0;
							 | 
						||
| 
								 | 
							
								                for (var j = 0; j < predictor_order; j++)
							 | 
						||
| 
								 | 
							
								                    sum += coeffs[j] * decoded[i - j - 1];
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								                decoded[i] += (sum >> qlevel);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            // simulate 64 bit integer using an array of two 32 bit ints
							 | 
						||
| 
								 | 
							
								            var total = this.lpc_total;
							 | 
						||
| 
								 | 
							
								            for (var i = predictor_order; i < blockSize; i++) {
							 | 
						||
| 
								 | 
							
								                // reset total to 0
							 | 
						||
| 
								 | 
							
								                total[0] = 0;
							 | 
						||
| 
								 | 
							
								                total[1] = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                for (j = 0; j < predictor_order; j++) {
							 | 
						||
| 
								 | 
							
								                    // simulate `total += coeffs[j] * decoded[i - j - 1]`
							 | 
						||
| 
								 | 
							
								                    multiply_add(total, coeffs[j], decoded[i - j - 1]);                    
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                // simulate `decoded[i] += total >> qlevel`
							 | 
						||
| 
								 | 
							
								                // we know that qlevel < 32 since it is a 5 bit field (see above)
							 | 
						||
| 
								 | 
							
								                decoded[i] += (total[0] >>> qlevel) | (total[1] << (32 - qlevel));
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    const TWO_PWR_32_DBL = Math.pow(2, 32);
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								    // performs `total += a * b` on a simulated 64 bit int
							 | 
						||
| 
								 | 
							
								    // total is an Int32Array(2)
							 | 
						||
| 
								 | 
							
								    // a and b are JS numbers (32 bit ints)
							 | 
						||
| 
								 | 
							
								    function multiply_add(total, a, b) {
							 | 
						||
| 
								 | 
							
								        // multiply a * b (we can use normal JS multiplication for this)
							 | 
						||
| 
								 | 
							
								        var r = a * b;
							 | 
						||
| 
								 | 
							
								        var n = r < 0;
							 | 
						||
| 
								 | 
							
								        if (n)
							 | 
						||
| 
								 | 
							
								            r = -r;
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								        var r_low = (r % TWO_PWR_32_DBL) | 0;
							 | 
						||
| 
								 | 
							
								        var r_high = (r / TWO_PWR_32_DBL) | 0;
							 | 
						||
| 
								 | 
							
								        if (n) {
							 | 
						||
| 
								 | 
							
								            r_low = ~r_low + 1;
							 | 
						||
| 
								 | 
							
								            r_high = ~r_high;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        // add result to total
							 | 
						||
| 
								 | 
							
								        var a48 = total[1] >>> 16;
							 | 
						||
| 
								 | 
							
								        var a32 = total[1] & 0xFFFF;
							 | 
						||
| 
								 | 
							
								        var a16 = total[0] >>> 16;
							 | 
						||
| 
								 | 
							
								        var a00 = total[0] & 0xFFFF;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var b48 = r_high >>> 16;
							 | 
						||
| 
								 | 
							
								        var b32 = r_high & 0xFFFF;
							 | 
						||
| 
								 | 
							
								        var b16 = r_low >>> 16;
							 | 
						||
| 
								 | 
							
								        var b00 = r_low & 0xFFFF;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
							 | 
						||
| 
								 | 
							
								        c00 += a00 + b00;
							 | 
						||
| 
								 | 
							
								        c16 += c00 >>> 16;
							 | 
						||
| 
								 | 
							
								        c00 &= 0xFFFF;
							 | 
						||
| 
								 | 
							
								        c16 += a16 + b16;
							 | 
						||
| 
								 | 
							
								        c32 += c16 >>> 16;
							 | 
						||
| 
								 | 
							
								        c16 &= 0xFFFF;
							 | 
						||
| 
								 | 
							
								        c32 += a32 + b32;
							 | 
						||
| 
								 | 
							
								        c48 += c32 >>> 16;
							 | 
						||
| 
								 | 
							
								        c32 &= 0xFFFF;
							 | 
						||
| 
								 | 
							
								        c48 += a48 + b48;
							 | 
						||
| 
								 | 
							
								        c48 &= 0xFFFF;
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        // store result back in total
							 | 
						||
| 
								 | 
							
								        total[0] = (c16 << 16) | c00;
							 | 
						||
| 
								 | 
							
								        total[1] = (c48 << 16) | c32;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								     
							 | 
						||
| 
								 | 
							
								    const INT_MAX = 32767;
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    this.prototype.decode_residuals = function(channel, predictor_order) {
							 | 
						||
| 
								 | 
							
								        var stream = this.bitstream,
							 | 
						||
| 
								 | 
							
								            method_type = stream.read(2);
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								        if (method_type > 1)
							 | 
						||
| 
								 | 
							
								            throw new Error('Illegal residual coding method ' + method_type);
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        var rice_order = stream.read(4),
							 | 
						||
| 
								 | 
							
								            samples = (this.blockSize >>> rice_order);
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								        if (predictor_order > samples)
							 | 
						||
| 
								 | 
							
								            throw new Error('Invalid predictor order ' + predictor_order + ' > ' + samples);
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        var decoded = this.decoded[channel],
							 | 
						||
| 
								 | 
							
								            sample = predictor_order, 
							 | 
						||
| 
								 | 
							
								            i = predictor_order;
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        for (var partition = 0; partition < (1 << rice_order); partition++) {
							 | 
						||
| 
								 | 
							
								            var tmp = stream.read(method_type === 0 ? 4 : 5);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (tmp === (method_type === 0 ? 15 : 31)) {
							 | 
						||
| 
								 | 
							
								                tmp = stream.read(5);
							 | 
						||
| 
								 | 
							
								                for (; i < samples; i++)
							 | 
						||
| 
								 | 
							
								                    decoded[sample++] = stream.read(tmp, true);
							 | 
						||
| 
								 | 
							
								                    
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                for (; i < samples; i++)
							 | 
						||
| 
								 | 
							
								                    decoded[sample++] = this.golomb(tmp, INT_MAX, 0);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								            i = 0;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    const MIN_CACHE_BITS = 25;
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    this.prototype.golomb = function(k, limit, esc_len) {
							 | 
						||
| 
								 | 
							
								        var data = this.bitstream,
							 | 
						||
| 
								 | 
							
								            offset = data.bitPosition,
							 | 
						||
| 
								 | 
							
								            buf = data.peek(32 - offset) << offset,
							 | 
						||
| 
								 | 
							
								            v = 0;
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        var log = 31 - clz(buf | 1); // log2(buf)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (log - k >= 32 - MIN_CACHE_BITS && 32 - log < limit) {
							 | 
						||
| 
								 | 
							
								            buf >>>= log - k;
							 | 
						||
| 
								 | 
							
								            buf += (30 - log) << k;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            data.advance(32 + k - log);
							 | 
						||
| 
								 | 
							
								            v = buf;
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            for (var i = 0; data.read(1) === 0; i++)
							 | 
						||
| 
								 | 
							
								                buf = data.peek(32 - offset) << offset;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (i < limit - 1) {
							 | 
						||
| 
								 | 
							
								                if (k)
							 | 
						||
| 
								 | 
							
								                    buf = data.read(k);
							 | 
						||
| 
								 | 
							
								                else
							 | 
						||
| 
								 | 
							
								                    buf = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                v = buf + (i << k);
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								            } else if (i === limit - 1) {
							 | 
						||
| 
								 | 
							
								                buf = data.read(esc_len);
							 | 
						||
| 
								 | 
							
								                v = buf + 1;
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                v = -1;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        return (v >> 1) ^ -(v & 1);
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    // Should be in the damned standard library...
							 | 
						||
| 
								 | 
							
								    function clz(input) {
							 | 
						||
| 
								 | 
							
								        var output = 0,
							 | 
						||
| 
								 | 
							
								            curbyte = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        while(true) { // emulate goto in JS using the break statement :D
							 | 
						||
| 
								 | 
							
								            curbyte = input >>> 24;
							 | 
						||
| 
								 | 
							
								            if (curbyte) break;
							 | 
						||
| 
								 | 
							
								            output += 8;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            curbyte = input >>> 16;
							 | 
						||
| 
								 | 
							
								            if (curbyte & 0xff) break;
							 | 
						||
| 
								 | 
							
								            output += 8;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            curbyte = input >>> 8;
							 | 
						||
| 
								 | 
							
								            if (curbyte & 0xff) break;
							 | 
						||
| 
								 | 
							
								            output += 8;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            curbyte = input;
							 | 
						||
| 
								 | 
							
								            if (curbyte & 0xff) break;
							 | 
						||
| 
								 | 
							
								            output += 8;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            return output;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (!(curbyte & 0xf0))
							 | 
						||
| 
								 | 
							
								            output += 4;
							 | 
						||
| 
								 | 
							
								        else
							 | 
						||
| 
								 | 
							
								            curbyte >>>= 4;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (curbyte & 0x8)
							 | 
						||
| 
								 | 
							
								            return output;
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								        if (curbyte & 0x4)
							 | 
						||
| 
								 | 
							
								            return output + 1;
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								        if (curbyte & 0x2)
							 | 
						||
| 
								 | 
							
								            return output + 2;
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								        if (curbyte & 0x1)
							 | 
						||
| 
								 | 
							
								            return output + 3;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // shouldn't get here
							 | 
						||
| 
								 | 
							
								        return output + 4;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = FLACDecoder;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								},{}],3:[function(require,module,exports){
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * FLAC.js - Free Lossless Audio Codec decoder in JavaScript
							 | 
						||
| 
								 | 
							
								 * By Devon Govett and Jens Nockert of Official.fm Labs
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * FLAC.js is free software; you can redistribute it and/or
							 | 
						||
| 
								 | 
							
								 * modify it under the terms of the GNU Lesser General Public
							 | 
						||
| 
								 | 
							
								 * License as published by the Free Software Foundation; either
							 | 
						||
| 
								 | 
							
								 * version 2.1 of the License, or (at your option) any later version.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * FLAC.js is distributed in the hope that it will be useful,
							 | 
						||
| 
								 | 
							
								 * but WITHOUT ANY WARRANTY; without even the implied warranty of
							 | 
						||
| 
								 | 
							
								 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
							 | 
						||
| 
								 | 
							
								 * Lesser General Public License for more details.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var AV = (window.AV);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var FLACDemuxer = AV.Demuxer.extend(function() {
							 | 
						||
| 
								 | 
							
								    AV.Demuxer.register(this);
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    this.probe = function(buffer) {
							 | 
						||
| 
								 | 
							
								        return buffer.peekString(0, 4) === 'fLaC';
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    const STREAMINFO = 0,
							 | 
						||
| 
								 | 
							
								          PADDING = 1,
							 | 
						||
| 
								 | 
							
								          APPLICATION = 2,
							 | 
						||
| 
								 | 
							
								          SEEKTABLE = 3,
							 | 
						||
| 
								 | 
							
								          VORBIS_COMMENT = 4,
							 | 
						||
| 
								 | 
							
								          CUESHEET = 5,
							 | 
						||
| 
								 | 
							
								          PICTURE = 6,
							 | 
						||
| 
								 | 
							
								          INVALID = 127,
							 | 
						||
| 
								 | 
							
								          STREAMINFO_SIZE = 34;
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    this.prototype.readChunk = function() {
							 | 
						||
| 
								 | 
							
								        var stream = this.stream;
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        if (!this.readHeader && stream.available(4)) {
							 | 
						||
| 
								 | 
							
								            if (stream.readString(4) !== 'fLaC')
							 | 
						||
| 
								 | 
							
								                return this.emit('error', 'Invalid FLAC file.');
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								            this.readHeader = true;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        while (stream.available(1) && !this.last) {                     
							 | 
						||
| 
								 | 
							
								            if (!this.readBlockHeaders) {
							 | 
						||
| 
								 | 
							
								                var tmp = stream.readUInt8();
							 | 
						||
| 
								 | 
							
								                this.last = (tmp & 0x80) === 0x80,
							 | 
						||
| 
								 | 
							
								                this.type = tmp & 0x7F,
							 | 
						||
| 
								 | 
							
								                this.size = stream.readUInt24();
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								            if (!this.foundStreamInfo && this.type !== STREAMINFO)
							 | 
						||
| 
								 | 
							
								                return this.emit('error', 'STREAMINFO must be the first block');
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								            if (!stream.available(this.size))
							 | 
						||
| 
								 | 
							
								                return;
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								            switch (this.type) {
							 | 
						||
| 
								 | 
							
								                case STREAMINFO:
							 | 
						||
| 
								 | 
							
								                    if (this.foundStreamInfo)
							 | 
						||
| 
								 | 
							
								                        return this.emit('error', 'STREAMINFO can only occur once.');
							 | 
						||
| 
								 | 
							
								                    
							 | 
						||
| 
								 | 
							
								                    if (this.size !== STREAMINFO_SIZE)
							 | 
						||
| 
								 | 
							
								                        return this.emit('error', 'STREAMINFO size is wrong.');
							 | 
						||
| 
								 | 
							
								                    
							 | 
						||
| 
								 | 
							
								                    this.foundStreamInfo = true;
							 | 
						||
| 
								 | 
							
								                    var bitstream = new AV.Bitstream(stream);
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								                    var cookie = {
							 | 
						||
| 
								 | 
							
								                        minBlockSize: bitstream.read(16),
							 | 
						||
| 
								 | 
							
								                        maxBlockSize: bitstream.read(16),
							 | 
						||
| 
								 | 
							
								                        minFrameSize: bitstream.read(24),
							 | 
						||
| 
								 | 
							
								                        maxFrameSize: bitstream.read(24)
							 | 
						||
| 
								 | 
							
								                    };
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								                    this.format = {
							 | 
						||
| 
								 | 
							
								                        formatID: 'flac',
							 | 
						||
| 
								 | 
							
								                        sampleRate: bitstream.read(20),
							 | 
						||
| 
								 | 
							
								                        channelsPerFrame: bitstream.read(3) + 1,
							 | 
						||
| 
								 | 
							
								                        bitsPerChannel: bitstream.read(5) + 1
							 | 
						||
| 
								 | 
							
								                    };
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								                    this.emit('format', this.format);
							 | 
						||
| 
								 | 
							
								                    this.emit('cookie', cookie);
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								                    var sampleCount = bitstream.read(36);
							 | 
						||
| 
								 | 
							
								                    this.emit('duration', sampleCount / this.format.sampleRate * 1000 | 0);
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								                    stream.advance(16); // skip MD5 hashes
							 | 
						||
| 
								 | 
							
								                    this.readBlockHeaders = false;
							 | 
						||
| 
								 | 
							
								                    break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    /*
							 | 
						||
| 
								 | 
							
								                    I am only looking at the least significant 32 bits of sample number and offset data
							 | 
						||
| 
								 | 
							
								                    This is more than sufficient for the longest flac file I have (~50 mins 2-channel 16-bit 44.1k which uses about 7.5% of the UInt32 space for the largest offset)
							 | 
						||
| 
								 | 
							
								                    Can certainly be improved by storing sample numbers and offests as doubles, but would require additional overriding of the searchTimestamp and seek functions (possibly more?)
							 | 
						||
| 
								 | 
							
								                    Also the flac faq suggests it would be possible to find frame lengths and thus create seek points on the fly via decoding but I assume this would be slow
							 | 
						||
| 
								 | 
							
								                    I may look into these thigns though as my project progresses
							 | 
						||
| 
								 | 
							
								                    */
							 | 
						||
| 
								 | 
							
								                    case SEEKTABLE:
							 | 
						||
| 
								 | 
							
								                        for(var s=0; s<this.size/18; s++)
							 | 
						||
| 
								 | 
							
								                        {
							 | 
						||
| 
								 | 
							
								                            if(stream.peekUInt32(0) == 0xFFFFFFFF && stream.peekUInt32(1) == 0xFFFFFFFF)
							 | 
						||
| 
								 | 
							
								                            {
							 | 
						||
| 
								 | 
							
								                                //placeholder, ignore
							 | 
						||
| 
								 | 
							
								                                stream.advance(18);
							 | 
						||
| 
								 | 
							
								                            } else {
							 | 
						||
| 
								 | 
							
								                                if(stream.readUInt32() > 0)
							 | 
						||
| 
								 | 
							
								                                {
							 | 
						||
| 
								 | 
							
								                                    this.emit('error', 'Seek points with sample number >UInt32 not supported');
							 | 
						||
| 
								 | 
							
								                                }
							 | 
						||
| 
								 | 
							
								                                var samplenum = stream.readUInt32();
							 | 
						||
| 
								 | 
							
								                                if(stream.readUInt32() > 0)
							 | 
						||
| 
								 | 
							
								                                {
							 | 
						||
| 
								 | 
							
								                                    this.emit('error', 'Seek points with stream offset >UInt32 not supported');
							 | 
						||
| 
								 | 
							
								                                }
							 | 
						||
| 
								 | 
							
								                                var offset = stream.readUInt32();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                                stream.advance(2);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                                this.addSeekPoint(offset, samplenum);
							 | 
						||
| 
								 | 
							
								                            }
							 | 
						||
| 
								 | 
							
								                        }
							 | 
						||
| 
								 | 
							
								                        break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                case VORBIS_COMMENT:
							 | 
						||
| 
								 | 
							
								                    // see http://www.xiph.org/vorbis/doc/v-comment.html
							 | 
						||
| 
								 | 
							
								                    this.metadata || (this.metadata = {});
							 | 
						||
| 
								 | 
							
								                    var len = stream.readUInt32(true);
							 | 
						||
| 
								 | 
							
								                    
							 | 
						||
| 
								 | 
							
								                    this.metadata.vendor = stream.readString(len);
							 | 
						||
| 
								 | 
							
								                    var length = stream.readUInt32(true);
							 | 
						||
| 
								 | 
							
								                    
							 | 
						||
| 
								 | 
							
								                    for (var i = 0; i < length; i++) {
							 | 
						||
| 
								 | 
							
								                        len = stream.readUInt32(true);
							 | 
						||
| 
								 | 
							
								                        var str = stream.readString(len, 'utf8'),
							 | 
						||
| 
								 | 
							
								                            idx = str.indexOf('=');
							 | 
						||
| 
								 | 
							
								                            
							 | 
						||
| 
								 | 
							
								                        this.metadata[str.slice(0, idx).toLowerCase()] = str.slice(idx + 1);
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    
							 | 
						||
| 
								 | 
							
								                    // TODO: standardize field names across formats
							 | 
						||
| 
								 | 
							
								                    break;
							 | 
						||
| 
								 | 
							
								                    
							 | 
						||
| 
								 | 
							
								                case PICTURE:
							 | 
						||
| 
								 | 
							
								                    var type = stream.readUInt32();
							 | 
						||
| 
								 | 
							
								                    if (type !== 3) { // make sure this is album art (type 3)
							 | 
						||
| 
								 | 
							
								                        stream.advance(this.size - 4);
							 | 
						||
| 
								 | 
							
								                    } else {
							 | 
						||
| 
								 | 
							
								                        var mimeLen = stream.readUInt32(),
							 | 
						||
| 
								 | 
							
								                            mime = stream.readString(mimeLen),
							 | 
						||
| 
								 | 
							
								                            descLen = stream.readUInt32(),
							 | 
						||
| 
								 | 
							
								                            description = stream.readString(descLen),
							 | 
						||
| 
								 | 
							
								                            width = stream.readUInt32(),
							 | 
						||
| 
								 | 
							
								                            height = stream.readUInt32(),
							 | 
						||
| 
								 | 
							
								                            depth = stream.readUInt32(),
							 | 
						||
| 
								 | 
							
								                            colors = stream.readUInt32(),
							 | 
						||
| 
								 | 
							
								                            length = stream.readUInt32(),
							 | 
						||
| 
								 | 
							
								                            picture = stream.readBuffer(length);
							 | 
						||
| 
								 | 
							
								                    
							 | 
						||
| 
								 | 
							
								                        this.metadata || (this.metadata = {});
							 | 
						||
| 
								 | 
							
								                        this.metadata.coverArt = picture;
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    
							 | 
						||
| 
								 | 
							
								                    // does anyone want the rest of the info?
							 | 
						||
| 
								 | 
							
								                    break;
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								                default:
							 | 
						||
| 
								 | 
							
								                    stream.advance(this.size);
							 | 
						||
| 
								 | 
							
								                    this.readBlockHeaders = false;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								            if (this.last && this.metadata)
							 | 
						||
| 
								 | 
							
								                this.emit('metadata', this.metadata);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        while (stream.available(1) && this.last) {
							 | 
						||
| 
								 | 
							
								            var buffer = stream.readSingleBuffer(stream.remainingBytes());
							 | 
						||
| 
								 | 
							
								            this.emit('data', buffer);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = FLACDemuxer;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								},{}],4:[function(require,module,exports){
							 | 
						||
| 
								 | 
							
								var AV = (window.AV);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// if ogg.js exists, register a plugin
							 | 
						||
| 
								 | 
							
								try {
							 | 
						||
| 
								 | 
							
								  var OggDemuxer = (window.AV.OggDemuxer);
							 | 
						||
| 
								 | 
							
								} catch (e) {};
							 | 
						||
| 
								 | 
							
								if (!OggDemuxer) return;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								OggDemuxer.plugins.push({
							 | 
						||
| 
								 | 
							
								  magic: "\177FLAC",
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								  init: function() {
							 | 
						||
| 
								 | 
							
								    this.list = new AV.BufferList();
							 | 
						||
| 
								 | 
							
								    this.stream = new AV.Stream(this.list);
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								  readHeaders: function(packet) {
							 | 
						||
| 
								 | 
							
								    var stream = this.stream;
							 | 
						||
| 
								 | 
							
								    this.list.append(new AV.Buffer(packet));
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    stream.advance(5); // magic
							 | 
						||
| 
								 | 
							
								    if (stream.readUInt8() != 1)
							 | 
						||
| 
								 | 
							
								      throw new Error('Unsupported FLAC version');
							 | 
						||
| 
								 | 
							
								      
							 | 
						||
| 
								 | 
							
								    stream.advance(3);
							 | 
						||
| 
								 | 
							
								    if (stream.peekString(0, 4) != 'fLaC')
							 | 
						||
| 
								 | 
							
								      throw new Error('Not flac');
							 | 
						||
| 
								 | 
							
								      
							 | 
						||
| 
								 | 
							
								    this.flac = AV.Demuxer.find(stream.peekSingleBuffer(0, stream.remainingBytes()));
							 | 
						||
| 
								 | 
							
								    if (!this.flac)
							 | 
						||
| 
								 | 
							
								      throw new Error('Flac demuxer not found');
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    this.flac.prototype.readChunk.call(this);
							 | 
						||
| 
								 | 
							
								    return true;
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								  readPacket: function(packet) {
							 | 
						||
| 
								 | 
							
								    this.list.append(new AV.Buffer(packet));
							 | 
						||
| 
								 | 
							
								    this.flac.prototype.readChunk.call(this);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								},{}]},{},[1])
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//# sourceMappingURL=flac.js.map
							 |