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
*
* @param {AudioletBuffer[]} inputBuffers Samples received from the inputs.
* @param {AudioletBuffer[]} outputBuffers Samples to be sent to the outputs.
*/
Limiter.prototype.generate = function(inputBuffers, outputBuffers) {
var inputBuffer = inputBuffers[0];
var outputBuffer = outputBuffers[0];

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

var followers = this.followers;
var numberOfFollowers = followers.length;
Limiter.prototype.generate = function() {
var input = this.inputs[0];
var output = this.outputs[0];

var sampleRate = this.audiolet.device.sampleRate;

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

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

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

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

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

var bufferLength = inputBuffer.length;
for (var j = 0; j < bufferLength; j++) {
// Get values from channels
var value = inputChannel[j];
if (attackChannel) {
attack = Math.pow(0.01, 1 / (attackChannel[j] * sampleRate));
}
if (releaseChannel) {
release = Math.pow(0.01, 1 / (releaseChannel[j] * sampleRate));
}
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;
}
var value = input.samples[i];

// Calculate amplitude envelope
var absValue = Math.abs(value);
if (absValue > follower) {
follower = attack * (follower - absValue) + absValue;
}
else {
follower = release * (follower - absValue) + absValue;
}
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
*
* @param {AudioletBuffer[]} inputBuffers Samples received from the inputs.
* @param {AudioletBuffer[]} outputBuffers Samples to be sent to the outputs.
*/
LinearCrossFade.prototype.generate = function(inputBuffers, outputBuffers) {
var inputBufferA = inputBuffers[0];
var inputBufferB = inputBuffers[1];
var outputBuffer = outputBuffers[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];
}
LinearCrossFade.prototype.generate = function() {
var inputA = this.inputs[0];
var inputB = this.inputs[1];
var output = this.outputs[0];

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

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

outputChannel[i] = inputChannelA[i] * gainA +
inputChannelB[i] * gainB;
}
var numberOfChannels = output.samples.length;
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
*
* @param {AudioletBuffer[]} inputBuffers Samples received from the inputs.
* @param {AudioletBuffer[]} outputBuffers Samples to be sent to the outputs.
*/
Pan.prototype.generate = function(inputBuffers, outputBuffers) {
var inputBuffer = inputBuffers[0];
var outputBuffer = outputBuffers[0];

if (inputBuffer.isEmpty) {
outputBuffer.isEmpty = true;
return;
}
Pan.prototype.generate = function() {
var input = this.inputs[0];
var output = this.outputs[0];

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

// Local processing variables
var panParameter = this.pan;
var pan, panChannel;
if (panParameter.isStatic()) {
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);
}
var value = input.samples[0] || 0;
var scaledPan = pan * Math.PI / 2;
output.samples[0] = value * Math.cos(scaledPan);
output.samples[1] = 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
*
* @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 roomSize = this.roomSize.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
*
* @param {AudioletBuffer[]} inputBuffers Samples received from the inputs.
* @param {AudioletBuffer[]} outputBuffers Samples to be sent to the outputs.
*/
SoftClip.prototype.generate = function(inputBuffers, outputBuffers) {
var inputBuffer = inputBuffers[0];
var outputBuffer = outputBuffers[0];

if (inputBuffer.isEmpty) {
outputBuffer.isEmpty = true;
return;
}
SoftClip.prototype.generate = function() {
var input = this.inputs[0];
var output = this.outputs[0];

var numberOfChannels = inputBuffer.numberOfChannels;
var numberOfChannels = input.samples.length;
for (var i = 0; i < numberOfChannels; i++) {
var inputChannel = inputBuffer.getChannelData(i);
var outputChannel = outputBuffer.getChannelData(i);
var bufferLength = inputBuffer.length;
for (var j = 0; j < bufferLength; j++) {
var value = inputChannel[j];
if (value > 0.5) {
outputChannel[j] = (value - 0.25) / value;
}
else if (value < -0.5) {
outputChannel[j] = (-value - 0.25) / value;
}
else {
outputChannel[j] = value;
}
var value = input.samples[i];
if (value > 0.5 || value < -0.5) {
output.samples[i] = (Math.abs(value) - 0.25) / value;
}
else {
output.samples[i] = 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
*
* @param {AudioletBuffer[]} inputBuffers Samples received from the inputs.
* @param {AudioletBuffer[]} outputBuffers Samples to be sent to the outputs.
*/
WhiteNoise.prototype.generate = function(inputBuffers, outputBuffers) {
var buffer = outputBuffers[0];
var channel = buffer.getChannelData(0);

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

/**
Expand Down

0 comments on commit 36cc03e

Please sign in to comment.