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, { readableObjectMode: 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 );
Iif( 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;
|