2013-12-30 10:50:54 +00:00
|
|
|
var
|
|
|
|
Readable = require('stream').Readable,
|
2013-12-31 10:06:42 +00:00
|
|
|
util = require('util'),
|
|
|
|
|
|
|
|
Input = require('./input.js')
|
2013-12-30 10:50:54 +00:00
|
|
|
;
|
|
|
|
|
|
|
|
function Mixer(args) {
|
2014-01-01 02:58:53 +00:00
|
|
|
Readable.call(this, args);
|
2013-12-30 10:50:54 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2014-01-01 02:58:53 +00:00
|
|
|
this.buffer = new Buffer(0);
|
|
|
|
|
2013-12-30 10:50:54 +00:00
|
|
|
this.bitDepth = args.bitDepth;
|
2014-01-01 00:27:03 +00:00
|
|
|
if (args.bitDepth == 8) {
|
2014-01-01 02:58:53 +00:00
|
|
|
this.readSample = this.buffer.readInt8;
|
|
|
|
this.writeSample = this.buffer.writeInt8;
|
2014-01-01 00:27:03 +00:00
|
|
|
this.sampleByteLength = 1;
|
|
|
|
}
|
|
|
|
else if (args.bitDepth == 32) {
|
2014-01-01 02:58:53 +00:00
|
|
|
this.readSample = this.buffer.readInt32LE;
|
|
|
|
this.writeSample = this.buffer.writeInt32LE;
|
2014-01-01 00:27:03 +00:00
|
|
|
this.sampleByteLength = 4;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
args.bitDepth = 16;
|
2014-01-01 02:58:53 +00:00
|
|
|
this.readSample = this.buffer.readInt16LE;
|
|
|
|
this.writeSample = this.buffer.writeInt16LE;
|
2014-01-01 00:27:03 +00:00
|
|
|
this.sampleByteLength = 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.channels = args.channels;
|
2013-12-30 10:50:54 +00:00
|
|
|
this.sampleRate = args.sampleRate;
|
|
|
|
|
|
|
|
this.inputs = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
util.inherits(Mixer, Readable);
|
|
|
|
|
|
|
|
Mixer.prototype._read = function() {
|
2014-01-01 00:27:03 +00:00
|
|
|
|
2014-01-01 02:58:53 +00:00
|
|
|
console.log('_read', arguments);
|
|
|
|
|
2014-01-01 00:27:03 +00:00
|
|
|
var samples = 9007199254740992;
|
|
|
|
this.inputs.forEach(function (input) {
|
|
|
|
var as = input.availSamples();
|
|
|
|
if (as < samples) samples = as;
|
|
|
|
});
|
2014-01-01 02:58:53 +00:00
|
|
|
if (samples > 0 && samples != 9007199254740992) {
|
|
|
|
console.log('read samples', samples);
|
2014-01-01 00:27:03 +00:00
|
|
|
|
2014-01-01 02:58:53 +00:00
|
|
|
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);
|
2014-01-01 00:27:03 +00:00
|
|
|
}
|
2014-01-01 02:58:53 +00:00
|
|
|
}.bind(this));
|
2014-01-01 00:27:03 +00:00
|
|
|
|
|
|
|
this.push(mixedBuffer);
|
2014-01-01 02:58:53 +00:00
|
|
|
} else {
|
|
|
|
console.log('Nothing to read.');
|
|
|
|
setImmediate(this._read.bind(this));
|
2014-01-01 00:27:03 +00:00
|
|
|
}
|
2013-12-30 10:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Mixer.prototype.input = function (args) {
|
|
|
|
if (typeof args === 'undefined') args = {};
|
|
|
|
|
|
|
|
var input = new Input({
|
2013-12-31 10:06:42 +00:00
|
|
|
mixer: this,
|
2013-12-30 10:50:54 +00:00
|
|
|
channels: args.channels || this.channels,
|
|
|
|
bitDepth: args.bitDepth || this.bitDepth,
|
|
|
|
sampleRate: args.sampleRate || this.sampleRate
|
|
|
|
});
|
|
|
|
this.inputs.push(input);
|
|
|
|
|
|
|
|
return input;
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = Mixer;
|