Skip to content

Commit c8d053f

Browse files
committed
Adds Quadrafuzz effect.
1 parent 268a3a4 commit c8d053f

13 files changed

Lines changed: 643 additions & 6 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
node_modules
22
logos
33
*.sublime-project
4-
*.sublime-workspace
4+
*.sublime-workspace
5+
*.pem

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Thank you for taking the time to read this. Pizzicato is on its very early stages and all help is welcome!
1+
Thank you for taking the time to read this, all help is welcome!
22

33
Make sure that all tests are passing and that you create new tests if necessary. You can execute the tests with the command `npm run test`. Also please make sure the documentation is updated.
44

README.md

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Pizzicato aims to simplify the way you create and manipulate sounds via the Web
3535
- [Ping Pong Delay](#pingpongdelay)
3636
- [Dub Delay](#dubdelay)
3737
- [Distortion](#distortion)
38+
- [Quadrafuzz](#quadrafuzz)
3839
- [Flanger](#flanger)
3940
- [Compressor](#compressor)
4041
- [Low-pass filter](#low-pass-filter)
@@ -469,6 +470,31 @@ sound.addEffect(delay);
469470
sound.play();
470471
```
471472

473+
<a name="quadrafuzz">
474+
### Quadrafuzz ([example](https://alemangui.github.io/pizzicato/#quadrafuzz))
475+
The quadrafuzz effect divides the sound into separate bands and then distorts each band independently, allowing you to control which frequencies you distort and how much.
476+
477+
The quadrafuzz code in Pizzicato is based on [Michel Buffa's](https://twitter.com/micbuffa) implementation of the quadrafuzz effect.
478+
479+
The effect takes the following parameters:
480+
* ```lowGain``` _(min: 0, max: 1, defaults to 0.6)_:
481+
* ```midLowGain``` _(min: 0, max: 1, defaults to 0.8)_:
482+
* ```midHighGain``` _(min: 0, max: 1, defaults to 0.5)_:
483+
* ```highGain``` _(min: 0, max: 1, defaults to 0.6)_:
484+
485+
Example:
486+
```javascript
487+
var quadrafuzz = new Pizzicato.Effects.Quadrafuzz({
488+
lowGain: 0.6,
489+
midLowGain: 0.8,
490+
midHighGain: 0.5,
491+
highGain: 0.6,
492+
});
493+
494+
sound.addEffect(quadrafuzz);
495+
sound.play();
496+
```
497+
472498
<a name="flanger"/>
473499
### Flanger ([example](https://alemangui.github.io/pizzicato/#flanger))
474500
The flanger produces a swirling effect by delaying a "copy" of the sound by a small, gradually changing period. The flanger effect takes the folloeing parameters:
@@ -702,9 +728,9 @@ All Pizzicato.Sound objects are connected to the context's destination by defaul
702728
To have a Pizzicato.Sound object that is not connected to the context's destination, use the ```detached``` option as follows:
703729

704730
```javascript
705-
var analyser = Pizzicato.context.createAnaliser();
731+
var analyser = Pizzicato.context.createAnalyser();
706732
var sound = new Pizzicato.Sound({
707-
source: wave,
733+
source: 'wave',
708734
options: {
709735
detached: true
710736
}

distr/Pizzicato.js

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2127,6 +2127,150 @@
21272127
}
21282128

21292129
});
2130+
Pizzicato.Effects.Quadrafuzz = function(options) {
2131+
2132+
this.options = {};
2133+
options = options || this.options;
2134+
2135+
var defaults = {
2136+
lowGain: 0.6,
2137+
midLowGain: 0.8,
2138+
midHighGain: 0.5,
2139+
highGain: 0.6
2140+
};
2141+
2142+
2143+
this.inputNode = Pz.context.createGain();
2144+
this.outputNode = Pz.context.createGain();
2145+
this.dryGainNode = Pz.context.createGain();
2146+
this.wetGainNode = Pz.context.createGain();
2147+
2148+
2149+
this.lowpassLeft = Pz.context.createBiquadFilter();
2150+
this.lowpassLeft.type = 'lowpass';
2151+
this.lowpassLeft.frequency.value = 147;
2152+
this.lowpassLeft.Q.value = 0.7071;
2153+
2154+
this.bandpass1Left = Pz.context.createBiquadFilter();
2155+
this.bandpass1Left.type = 'bandpass';
2156+
this.bandpass1Left.frequency.value = 587;
2157+
this.bandpass1Left.Q.value = 0.7071;
2158+
2159+
this.bandpass2Left = Pz.context.createBiquadFilter();
2160+
this.bandpass2Left.type = 'bandpass';
2161+
this.bandpass2Left.frequency.value = 2490;
2162+
this.bandpass2Left.Q.value = 0.7071;
2163+
2164+
this.highpassLeft = Pz.context.createBiquadFilter();
2165+
this.highpassLeft.type = 'highpass';
2166+
this.highpassLeft.frequency.value = 4980;
2167+
this.highpassLeft.Q.value = 0.7071;
2168+
2169+
2170+
this.overdrives = [];
2171+
for (var i = 0; i < 4; i++) {
2172+
this.overdrives[i] = Pz.context.createWaveShaper();
2173+
this.overdrives[i].curve = getDistortionCurve();
2174+
}
2175+
2176+
2177+
this.inputNode.connect(this.wetGainNode);
2178+
this.inputNode.connect(this.dryGainNode);
2179+
this.dryGainNode.connect(this.outputNode);
2180+
2181+
var filters = [this.lowpassLeft, this.bandpass1Left, this.bandpass2Left, this.highpassLeft];
2182+
for (i = 0; i < filters.length; i++) {
2183+
this.wetGainNode.connect(filters[i]);
2184+
filters[i].connect(this.overdrives[i]);
2185+
this.overdrives[i].connect(this.outputNode);
2186+
}
2187+
2188+
for (var key in defaults) {
2189+
this[key] = options[key];
2190+
this[key] = (this[key] === undefined || this[key] === null) ? defaults[key] : this[key];
2191+
}
2192+
};
2193+
2194+
function getDistortionCurve(gain) {
2195+
var sampleRate = Pz.context.sampleRate;
2196+
var curve = new Float32Array(sampleRate);
2197+
var deg = Math.PI / 180;
2198+
2199+
for (var i = 0; i < sampleRate; i++) {
2200+
var x = i * 2 / sampleRate - 1;
2201+
curve[i] = (3 + gain) * x * 20 * deg / (Math.PI + gain * Math.abs(x));
2202+
}
2203+
return curve;
2204+
}
2205+
2206+
Pizzicato.Effects.Quadrafuzz.prototype = Object.create(baseEffect, {
2207+
2208+
lowGain: {
2209+
enumerable: true,
2210+
2211+
get: function() {
2212+
return this.options.lowGain;
2213+
},
2214+
2215+
set: function(lowGain) {
2216+
if (!Pz.Util.isInRange(lowGain, 0, 1))
2217+
return;
2218+
2219+
this.options.lowGain = lowGain;
2220+
this.overdrives[0].curve = getDistortionCurve(Pz.Util.normalize(this.lowGain, 0, 150));
2221+
}
2222+
},
2223+
2224+
midLowGain: {
2225+
enumerable: true,
2226+
2227+
get: function() {
2228+
return this.options.midLowGain;
2229+
},
2230+
2231+
set: function(midLowGain) {
2232+
if (!Pz.Util.isInRange(midLowGain, 0, 1))
2233+
return;
2234+
2235+
this.options.midLowGain = midLowGain;
2236+
this.overdrives[1].curve = getDistortionCurve(Pz.Util.normalize(this.midLowGain, 0, 150));
2237+
}
2238+
},
2239+
2240+
midHighGain: {
2241+
enumerable: true,
2242+
2243+
get: function() {
2244+
return this.options.midHighGain;
2245+
},
2246+
2247+
set: function(midHighGain) {
2248+
if (!Pz.Util.isInRange(midHighGain, 0, 1))
2249+
return;
2250+
2251+
this.options.midHighGain = midHighGain;
2252+
this.overdrives[2].curve = getDistortionCurve(Pz.Util.normalize(this.midHighGain, 0, 150));
2253+
}
2254+
},
2255+
2256+
highGain: {
2257+
enumerable: true,
2258+
2259+
get: function() {
2260+
return this.options.highGain;
2261+
},
2262+
2263+
set: function(highGain) {
2264+
if (!Pz.Util.isInRange(highGain, 0, 1))
2265+
return;
2266+
2267+
this.options.highGain = highGain;
2268+
this.overdrives[3].curve = getDistortionCurve(Pz.Util.normalize(this.highGain, 0, 150));
2269+
}
2270+
}
2271+
});
2272+
2273+
21302274

21312275
return Pizzicato;
21322276
})(typeof window !== "undefined" ? window : global);

distr/Pizzicato.min.js

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,4 @@
4040
"sound effects"
4141
],
4242
"main": "./distr/Pizzicato.min.js"
43-
}
43+
}

site/Pizzicato.js

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2127,6 +2127,150 @@
21272127
}
21282128

21292129
});
2130+
Pizzicato.Effects.Quadrafuzz = function(options) {
2131+
2132+
this.options = {};
2133+
options = options || this.options;
2134+
2135+
var defaults = {
2136+
lowGain: 0.6,
2137+
midLowGain: 0.8,
2138+
midHighGain: 0.5,
2139+
highGain: 0.6
2140+
};
2141+
2142+
2143+
this.inputNode = Pz.context.createGain();
2144+
this.outputNode = Pz.context.createGain();
2145+
this.dryGainNode = Pz.context.createGain();
2146+
this.wetGainNode = Pz.context.createGain();
2147+
2148+
2149+
this.lowpassLeft = Pz.context.createBiquadFilter();
2150+
this.lowpassLeft.type = 'lowpass';
2151+
this.lowpassLeft.frequency.value = 147;
2152+
this.lowpassLeft.Q.value = 0.7071;
2153+
2154+
this.bandpass1Left = Pz.context.createBiquadFilter();
2155+
this.bandpass1Left.type = 'bandpass';
2156+
this.bandpass1Left.frequency.value = 587;
2157+
this.bandpass1Left.Q.value = 0.7071;
2158+
2159+
this.bandpass2Left = Pz.context.createBiquadFilter();
2160+
this.bandpass2Left.type = 'bandpass';
2161+
this.bandpass2Left.frequency.value = 2490;
2162+
this.bandpass2Left.Q.value = 0.7071;
2163+
2164+
this.highpassLeft = Pz.context.createBiquadFilter();
2165+
this.highpassLeft.type = 'highpass';
2166+
this.highpassLeft.frequency.value = 4980;
2167+
this.highpassLeft.Q.value = 0.7071;
2168+
2169+
2170+
this.overdrives = [];
2171+
for (var i = 0; i < 4; i++) {
2172+
this.overdrives[i] = Pz.context.createWaveShaper();
2173+
this.overdrives[i].curve = getDistortionCurve();
2174+
}
2175+
2176+
2177+
this.inputNode.connect(this.wetGainNode);
2178+
this.inputNode.connect(this.dryGainNode);
2179+
this.dryGainNode.connect(this.outputNode);
2180+
2181+
var filters = [this.lowpassLeft, this.bandpass1Left, this.bandpass2Left, this.highpassLeft];
2182+
for (i = 0; i < filters.length; i++) {
2183+
this.wetGainNode.connect(filters[i]);
2184+
filters[i].connect(this.overdrives[i]);
2185+
this.overdrives[i].connect(this.outputNode);
2186+
}
2187+
2188+
for (var key in defaults) {
2189+
this[key] = options[key];
2190+
this[key] = (this[key] === undefined || this[key] === null) ? defaults[key] : this[key];
2191+
}
2192+
};
2193+
2194+
function getDistortionCurve(gain) {
2195+
var sampleRate = Pz.context.sampleRate;
2196+
var curve = new Float32Array(sampleRate);
2197+
var deg = Math.PI / 180;
2198+
2199+
for (var i = 0; i < sampleRate; i++) {
2200+
var x = i * 2 / sampleRate - 1;
2201+
curve[i] = (3 + gain) * x * 20 * deg / (Math.PI + gain * Math.abs(x));
2202+
}
2203+
return curve;
2204+
}
2205+
2206+
Pizzicato.Effects.Quadrafuzz.prototype = Object.create(baseEffect, {
2207+
2208+
lowGain: {
2209+
enumerable: true,
2210+
2211+
get: function() {
2212+
return this.options.lowGain;
2213+
},
2214+
2215+
set: function(lowGain) {
2216+
if (!Pz.Util.isInRange(lowGain, 0, 1))
2217+
return;
2218+
2219+
this.options.lowGain = lowGain;
2220+
this.overdrives[0].curve = getDistortionCurve(Pz.Util.normalize(this.lowGain, 0, 150));
2221+
}
2222+
},
2223+
2224+
midLowGain: {
2225+
enumerable: true,
2226+
2227+
get: function() {
2228+
return this.options.midLowGain;
2229+
},
2230+
2231+
set: function(midLowGain) {
2232+
if (!Pz.Util.isInRange(midLowGain, 0, 1))
2233+
return;
2234+
2235+
this.options.midLowGain = midLowGain;
2236+
this.overdrives[1].curve = getDistortionCurve(Pz.Util.normalize(this.midLowGain, 0, 150));
2237+
}
2238+
},
2239+
2240+
midHighGain: {
2241+
enumerable: true,
2242+
2243+
get: function() {
2244+
return this.options.midHighGain;
2245+
},
2246+
2247+
set: function(midHighGain) {
2248+
if (!Pz.Util.isInRange(midHighGain, 0, 1))
2249+
return;
2250+
2251+
this.options.midHighGain = midHighGain;
2252+
this.overdrives[2].curve = getDistortionCurve(Pz.Util.normalize(this.midHighGain, 0, 150));
2253+
}
2254+
},
2255+
2256+
highGain: {
2257+
enumerable: true,
2258+
2259+
get: function() {
2260+
return this.options.highGain;
2261+
},
2262+
2263+
set: function(highGain) {
2264+
if (!Pz.Util.isInRange(highGain, 0, 1))
2265+
return;
2266+
2267+
this.options.highGain = highGain;
2268+
this.overdrives[3].curve = getDistortionCurve(Pz.Util.normalize(this.highGain, 0, 150));
2269+
}
2270+
}
2271+
});
2272+
2273+
21302274

21312275
return Pizzicato;
21322276
})(typeof window !== "undefined" ? window : global);

site/audio/drum-fill.m4a

97.9 KB
Binary file not shown.

0 commit comments

Comments
 (0)