forked from Supositware/Haha-Yes
87 lines
1.9 KiB
JavaScript
87 lines
1.9 KiB
JavaScript
|
|
||
|
var util = require( 'util' );
|
||
|
var Transform = require( 'stream' ).Transform;
|
||
|
var ogg_packet = require( 'ogg-packet' );
|
||
|
|
||
|
var OpusEncoder = require( './OpusEncoder' );
|
||
|
|
||
|
var Decoder = function( rate, channels, frameSize ) {
|
||
|
Transform.call( this, { writableObjectMode: true } );
|
||
|
|
||
|
this.rate = rate || 48000;
|
||
|
this.channels = channels || 1;
|
||
|
this.frameSize = frameSize || this.rate * 0.04;
|
||
|
|
||
|
this.encoder = null;
|
||
|
|
||
|
this.header = {};
|
||
|
this.tags = null;
|
||
|
this.pos = 0;
|
||
|
this.samplesWritten = 0;
|
||
|
|
||
|
this.packetBuffer = [];
|
||
|
};
|
||
|
util.inherits( Decoder, Transform );
|
||
|
|
||
|
/**
|
||
|
* Transform stream callback
|
||
|
*/
|
||
|
Decoder.prototype._transform = function( packet, encoding, done ) {
|
||
|
|
||
|
// Write the header if it hasn't been written yet
|
||
|
if( !this.encoder ) {
|
||
|
this._parseHeader( packet );
|
||
|
} else if( !this.tags ) {
|
||
|
// TODO: Not implemented
|
||
|
// this._parseTags( packet );
|
||
|
this.tags = {};
|
||
|
} else {
|
||
|
this._processInput( packet );
|
||
|
}
|
||
|
|
||
|
done();
|
||
|
};
|
||
|
|
||
|
Decoder.prototype._parseHeader = function( packet ) {
|
||
|
|
||
|
var header = packet.packet;
|
||
|
|
||
|
var signature = header.slice( 0, 8 );
|
||
|
if( signature.toString( 'ascii' ) !== 'OpusHead' ) {
|
||
|
return this.emit( 'error', 'Bad header' );
|
||
|
}
|
||
|
|
||
|
this.header.version = header.readUInt8( 8 );
|
||
|
this.header.channels = header.readUInt8( 9 );
|
||
|
this.header.preSkip = header.readUInt16LE( 10 );
|
||
|
this.header.rate = header.readUInt32LE( 12 );
|
||
|
this.header.gain = header.readUInt16LE( 16 );
|
||
|
this.header.channelMap = header.readUInt8( 18 );
|
||
|
|
||
|
this.emit( 'format', {
|
||
|
channels: this.channels,
|
||
|
sampleRate: this.rate,
|
||
|
bitDepth: 16,
|
||
|
float: false,
|
||
|
signed: true,
|
||
|
|
||
|
gain: this.header.gain,
|
||
|
preSkip: this.header.preSkip,
|
||
|
version: this.header.version
|
||
|
});
|
||
|
|
||
|
this.encoder = new OpusEncoder( this.rate, this.channels );
|
||
|
};
|
||
|
|
||
|
Decoder.prototype._processInput = function( packet ) {
|
||
|
|
||
|
var frame = packet.packet;
|
||
|
|
||
|
var pcm = this.encoder.decode( frame );
|
||
|
this.push( pcm );
|
||
|
};
|
||
|
|
||
|
module.exports = Decoder;
|
||
|
|
||
|
|