var Readable = require('stream').Readable, util = require('util'), Input = require('./input.js') ; function Mixer(args) { Readable.call(this, args); if (typeof args === 'undefined') args = {}; if (args.channels != 1 && args.channels != 2) args.channels = 2; if (typeof args.sampleRate === 'number' || args.sampleRate < 1) args.sampleRate = 44100; this.buffer = new Buffer(0); this.bitDepth = args.bitDepth; if (args.bitDepth == 8) { this.readSample = this.buffer.readInt8; this.writeSample = this.buffer.writeInt8; this.sampleByteLength = 1; } else if (args.bitDepth == 32) { this.readSample = this.buffer.readInt32LE; this.writeSample = this.buffer.writeInt32LE; this.sampleByteLength = 4; } else { args.bitDepth = 16; this.readSample = this.buffer.readInt16LE; this.writeSample = this.buffer.writeInt16LE; this.sampleByteLength = 2; } this.channels = args.channels; this.sampleRate = args.sampleRate; this.inputs = []; } util.inherits(Mixer, Readable); Mixer.prototype._read = function() { console.log('_read', arguments); var samples = 9007199254740992; this.inputs.forEach(function (input) { var as = input.availSamples(); if (as < samples) samples = as; }); if (samples > 0 && samples != 9007199254740992) { console.log('read samples', samples); var mixedBuffer = new Buffer(samples * this.sampleByteLength * this.channels); mixedBuffer.fill(0); this.inputs.forEach(function (input) { if (this.channels == 1) { var inputBuffer = input.readMono(samples); } else { var inputBuffer = input.readStereo(samples); } for (var i = 0; i < samples * this.channels; i++) { this.writeSample.call(mixedBuffer, this.readSample.call(mixedBuffer, i * this.sampleByteLength) + Math.round(this.readSample.call(inputBuffer, i * this.sampleByteLength) / this.inputs.length), i * this.sampleByteLength); } }.bind(this)); this.push(mixedBuffer); } else { console.log('Nothing to read.'); setImmediate(this._read.bind(this)); } } Mixer.prototype.input = function (args) { if (typeof args === 'undefined') args = {}; var input = new Input({ mixer: this, channels: args.channels || this.channels, bitDepth: args.bitDepth || this.bitDepth, sampleRate: args.sampleRate || this.sampleRate }); this.inputs.push(input); return input; } module.exports = Mixer;