Skip to content

Commit

Permalink
More conversions to single-sample. Nearly done...
Browse files Browse the repository at this point in the history
  • Loading branch information
oampo committed Feb 12, 2012
1 parent 039cc5d commit 36cc03e
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 195 deletions.
105 changes: 29 additions & 76 deletions src/dsp/Limiter.js
Expand Up @@ -44,96 +44,49 @@ extend(Limiter, AudioletNode);


/** /**
* Process a block of samples * Process a block of samples
*
* @param {AudioletBuffer[]} inputBuffers Samples received from the inputs.
* @param {AudioletBuffer[]} outputBuffers Samples to be sent to the outputs.
*/ */
Limiter.prototype.generate = function(inputBuffers, outputBuffers) { Limiter.prototype.generate = function() {
var inputBuffer = inputBuffers[0]; var input = this.inputs[0];
var outputBuffer = outputBuffers[0]; var output = this.outputs[0];

if (inputBuffer.isEmpty) {
outputBuffer.isEmpty = true;
return;
}

var followers = this.followers;
var numberOfFollowers = followers.length;


var sampleRate = this.audiolet.device.sampleRate; var sampleRate = this.audiolet.device.sampleRate;


// Local processing variables // Local processing variables
var attackParameter = this.attack; var attack = Math.pow(0.01, 1 / (this.attack.getValue() *
var attack, attackChannel;
if (attackParameter.isStatic()) {
attack = Math.pow(0.01, 1 / (attackParameter.getValue() *
sampleRate)); sampleRate));
} var release = Math.pow(0.01, 1 / (this.release.getValue() *
else {
attackChannel = attackParameter.getChannel();
}

var releaseParameter = this.release;
var release, releaseChannel;
if (releaseParameter.isStatic()) {
release = Math.pow(0.01, 1 / (releaseParameter.getValue() *
sampleRate)); sampleRate));
}
else {
releaseChannel = releaseParameter.getChannel();
}


var thresholdParameter = this.threshold; var threshold = this.threshold.getValue();
var threshold, thresholdChannel;
if (thresholdParameter.isStatic()) {
threshold = thresholdParameter.getValue();
}
else {
thresholdChannel = thresholdParameter.getChannel();
}


var numberOfChannels = inputBuffer.numberOfChannels; var numberOfChannels = input.samples.length;
for (var i = 0; i < numberOfChannels; i++) { for (var i = 0; i < numberOfChannels; i++) {
if (i >= numberOfFollowers) { if (i >= this.followers.length) {
followers.push(0); this.followers.push(0);
} }
var follower = followers[i];


var inputChannel = inputBuffer.getChannelData(i); var follower = this.followers[i];
var outputChannel = outputBuffer.getChannelData(i);


var bufferLength = inputBuffer.length; var value = input.samples[i];
for (var j = 0; j < bufferLength; j++) {
// Get values from channels // Calculate amplitude envelope
var value = inputChannel[j]; var absValue = Math.abs(value);
if (attackChannel) { if (absValue > follower) {
attack = Math.pow(0.01, 1 / (attackChannel[j] * sampleRate)); follower = attack * (follower - absValue) + absValue;
} }
if (releaseChannel) { else {
release = Math.pow(0.01, 1 / (releaseChannel[j] * sampleRate)); follower = release * (follower - absValue) + absValue;
}
if (thresholdChannel) {
threshold = thresholdChannel[j];
}

// Calculate amplitude envelope
var absValue = Math.abs(value);
if (absValue > follower) {
follower = attack * (follower - absValue) + absValue;
}
else {
follower = release * (follower - absValue) + absValue;
}

var diff = follower - threshold;
if (diff > 0) {
outputChannel[j] = value / (1 + diff);
}
else {
outputChannel[j] = value;
}
} }
followers[i] = follower;
var diff = follower - threshold;
if (diff > 0) {
output.samples[i] = value / (1 + diff);
}
else {
output.samples[i] = value;
}

this.followers[i] = follower;
} }
}; };


Expand Down
54 changes: 12 additions & 42 deletions src/dsp/LinearCrossFade.js
Expand Up @@ -34,52 +34,22 @@ extend(LinearCrossFade, AudioletNode);


/** /**
* Process a block of samples * Process a block of samples
*
* @param {AudioletBuffer[]} inputBuffers Samples received from the inputs.
* @param {AudioletBuffer[]} outputBuffers Samples to be sent to the outputs.
*/ */
LinearCrossFade.prototype.generate = function(inputBuffers, outputBuffers) { LinearCrossFade.prototype.generate = function() {
var inputBufferA = inputBuffers[0]; var inputA = this.inputs[0];
var inputBufferB = inputBuffers[1]; var inputB = this.inputs[1];
var outputBuffer = outputBuffers[0]; var output = this.outputs[0];

var inputChannelsA = inputBufferA.channels;
var inputChannelsB = inputBufferB.channels;
var outputChannels = outputBuffer.channels;

if (inputBufferA.isEmpty || inputBufferB.isEmpty) {
outputBuffer.isEmpty = true;
return;
}

// Local processing variables
var positionParameter = this.position;
var position, positionChannel;
if (positionParameter.isStatic()) {
position = positionParameter.getValue();
}
else {
positionChannel = positionParameter.getChannel();
}

var bufferLength = outputBuffer.length;
for (var i = 0; i < bufferLength; i++) {
if (positionChannel) {
position = positionChannel[i];
}


var gainA = 1 - position; var position = this.position.getValue();
var gainB = position;


var numberOfChannels = inputBufferA.numberOfChannels; var gainA = 1 - position;
for (var j = 0; j < numberOfChannels; j++) { var gainB = position;
var inputChannelA = inputChannelsA[j];
var inputChannelB = inputChannelsB[j];
var outputChannel = outputChannels[j];


outputChannel[i] = inputChannelA[i] * gainA + var numberOfChannels = output.samples.length;
inputChannelB[i] * gainB; for (var i = 0; i < numberOfChannels; i++) {
} var valueA = inputA.samples[i] || 0;
var valueB = inputB.samples[i] || 0;
output.samples[i] = valueA * gainA + valueB * gainB;
} }
}; };


Expand Down
43 changes: 8 additions & 35 deletions src/dsp/Pan.js
Expand Up @@ -37,44 +37,17 @@ extend(Pan, AudioletNode);


/** /**
* Process a block of samples * Process a block of samples
*
* @param {AudioletBuffer[]} inputBuffers Samples received from the inputs.
* @param {AudioletBuffer[]} outputBuffers Samples to be sent to the outputs.
*/ */
Pan.prototype.generate = function(inputBuffers, outputBuffers) { Pan.prototype.generate = function() {
var inputBuffer = inputBuffers[0]; var input = this.inputs[0];
var outputBuffer = outputBuffers[0]; var output = this.outputs[0];

if (inputBuffer.isEmpty) {
outputBuffer.isEmpty = true;
return;
}


var inputChannel = inputBuffer.getChannelData(0); var pan = this.pan.getValue();
var leftOutputChannel = outputBuffer.getChannelData(0);
var rightOutputChannel = outputBuffer.getChannelData(1);


// Local processing variables var value = input.samples[0] || 0;
var panParameter = this.pan; var scaledPan = pan * Math.PI / 2;
var pan, panChannel; output.samples[0] = value * Math.cos(scaledPan);
if (panParameter.isStatic()) { output.samples[1] = value * Math.sin(scaledPan);
pan = panParameter.getValue();
}
else {
panChannel = panParameter.getChannel();
}

var bufferLength = outputBuffer.length;
for (var i = 0; i < bufferLength; i++) {
if (panChannel) {
pan = panChannel[i];
}
var scaledPan = pan * Math.PI / 2;
var value = inputChannel[i];
// TODO: Use sine/cos tables?
leftOutputChannel[i] = value * Math.cos(scaledPan);
rightOutputChannel[i] = value * Math.sin(scaledPan);
}
}; };


/** /**
Expand Down
5 changes: 1 addition & 4 deletions src/dsp/Reverb.js
Expand Up @@ -89,11 +89,8 @@ extend(Reverb, AudioletNode);


/** /**
* Process a block of samples * Process a block of samples
*
* @param {AudioletBuffer[]} inputBuffers Samples received from the inputs.
* @param {AudioletBuffer[]} outputBuffers Samples to be sent to the outputs.
*/ */
Reverb.prototype.generate = function(inputBuffers, outputBuffers) { Reverb.prototype.generate = function() {
var mix = this.mix.getValue(); var mix = this.mix.getValue();
var roomSize = this.roomSize.getValue(); var roomSize = this.roomSize.getValue();
var damping = this.damping.getValue(); var damping = this.damping.getValue();
Expand Down
36 changes: 10 additions & 26 deletions src/dsp/SoftClip.js
Expand Up @@ -26,35 +26,19 @@ extend(SoftClip, AudioletNode);


/** /**
* Process a block of samples * Process a block of samples
*
* @param {AudioletBuffer[]} inputBuffers Samples received from the inputs.
* @param {AudioletBuffer[]} outputBuffers Samples to be sent to the outputs.
*/ */
SoftClip.prototype.generate = function(inputBuffers, outputBuffers) { SoftClip.prototype.generate = function() {
var inputBuffer = inputBuffers[0]; var input = this.inputs[0];
var outputBuffer = outputBuffers[0]; var output = this.outputs[0];

if (inputBuffer.isEmpty) {
outputBuffer.isEmpty = true;
return;
}


var numberOfChannels = inputBuffer.numberOfChannels; var numberOfChannels = input.samples.length;
for (var i = 0; i < numberOfChannels; i++) { for (var i = 0; i < numberOfChannels; i++) {
var inputChannel = inputBuffer.getChannelData(i); var value = input.samples[i];
var outputChannel = outputBuffer.getChannelData(i); if (value > 0.5 || value < -0.5) {
var bufferLength = inputBuffer.length; output.samples[i] = (Math.abs(value) - 0.25) / value;
for (var j = 0; j < bufferLength; j++) { }
var value = inputChannel[j]; else {
if (value > 0.5) { output.samples[i] = value;
outputChannel[j] = (value - 0.25) / value;
}
else if (value < -0.5) {
outputChannel[j] = (-value - 0.25) / value;
}
else {
outputChannel[j] = value;
}
} }
} }
}; };
Expand Down
14 changes: 2 additions & 12 deletions src/dsp/WhiteNoise.js
Expand Up @@ -20,19 +20,9 @@ extend(WhiteNoise, AudioletNode);


/** /**
* Process a block of samples * Process a block of samples
*
* @param {AudioletBuffer[]} inputBuffers Samples received from the inputs.
* @param {AudioletBuffer[]} outputBuffers Samples to be sent to the outputs.
*/ */
WhiteNoise.prototype.generate = function(inputBuffers, outputBuffers) { WhiteNoise.prototype.generate = function() {
var buffer = outputBuffers[0]; this.outputs[0].samples[0] = Math.random() * 2 - 1;
var channel = buffer.getChannelData(0);

// Processing loop
var bufferLength = buffer.length;
for (var i = 0; i < bufferLength; i++) {
channel[i] = Math.random() * 2 - 1;
}
}; };


/** /**
Expand Down

0 comments on commit 36cc03e

Please sign in to comment.