-
-
Notifications
You must be signed in to change notification settings - Fork 682
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #96 from processing/newTone
envelope improvements
- Loading branch information
Showing
27 changed files
with
3,364 additions
and
757 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<title>bells_envelope_test</title> | ||
<script language="javascript" type="text/javascript" src="../../lib/p5.js"></script> | ||
<script language="javascript" type="text/javascript" src="../../lib/addons/p5.dom.js"></script> | ||
<script language="javascript" type="text/javascript" src="../../lib/p5.sound.js"></script> | ||
|
||
<script src="sketch.js" type="text/javascript"></script> | ||
|
||
<style> body {padding: 0; margin: 0;} canvas {vertical-align: top;} </style> | ||
</head> | ||
<body> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
|
||
// This example shows a more complex use of the .ramp function for the envelope. | ||
// You can use it to make a simple attack/decay envelope for struck or plucked style notes. | ||
// Here, we're creating synthetic bells using additive synthesis, and triggering each of their attacks and decays differently to make different harmonics last for different times. | ||
// Have fun! - Jeff Snyder | ||
var osc = []; | ||
var envelope = []; | ||
var fft; | ||
var myPhraseAttack, myPhraseRelease, myPart; | ||
var atPattern = [1, 1,1,1,0,1,1,1,1,0,0,0,0]; // this rhythmic pattern puts some rests in there | ||
var patternArray = [0,1,2,3,3,2,0,1]; // pattern of the notes (in terms of array indices from scaleArray) | ||
var scaleArray = [64, 60, 62, 55]; // classic bell tune | ||
var harmonicsArray = [.5, 1., 1.183, 1.506, 2., 2.514, 2.662, 3.011, 4.166, 5.433, 6.796, 8.215]; // bell partials taken from https://en.wikipedia.org/wiki/Strike_tone | ||
var idealArray = [.5, 1., 1.2, 1.5, 2, 2.5, 2.6667, 3.0, 4.0, 5.3333, 6.6667, 8.0]; // ideal bell partials | ||
var note = 0; | ||
var startPoint = 0; | ||
var endPoint = 0; | ||
var numWaveforms = 100; | ||
var numOsc = 12; // reduce this to reduce the number of overtones, 4 makes a nice, dark gamelan sound | ||
var numNotes = 4; | ||
var rawImpulse; | ||
var cVerb; | ||
var oscVols = []; | ||
var firstNote = 1; | ||
var pitchRatio = .8; //change this to transpose things around | ||
var pitchDeviation = .001; | ||
var idealOrReal = 0; // change this to 1 to change to an ideal bell instead of a measured bell | ||
var maxAttack = .001; // in seconds ... setting to .001 makes things very percussive, setting to > 1 makes them sound far away | ||
var maxDecay = 9.0; // in seconds ... short times make for deader bells | ||
var percentWashed = 0.0; | ||
var washedMax = 4; | ||
|
||
|
||
function preload() | ||
{ | ||
// create a p5.Convolver | ||
cVerb = createConvolver('assets/LadyChapelStAlbansCathedral.wav'); | ||
|
||
} | ||
|
||
function setup() | ||
{ | ||
createCanvas(1000, 400); | ||
rawImpulse = loadSound('assets/' + cVerb.impulses[0].name); | ||
|
||
for (var i = 0; i < numNotes; i++) | ||
{ | ||
// make the arrays into 2D arrays | ||
osc[i] = []; | ||
envelope[i] = []; | ||
oscVols[i] = []; | ||
var midiValue = scaleArray[i]; | ||
var freqValue = midiToFreq(midiValue); | ||
|
||
for(var j = 0; j < numOsc; j++) | ||
{ | ||
// make arrays of sine waves for each note, additive synthesis, and assign independent envelopes, amplitudes, and slight detunings for each harmonic | ||
osc[i][j] = new p5.SinOsc(); | ||
envelope[i][j] = new p5.Env(); | ||
if (random(0, 1) > percentWashed) | ||
{ | ||
myMaxAttack = maxAttack; | ||
print("normal"); | ||
} | ||
else | ||
{ | ||
myMaxAttack = washedMax; | ||
print("washed"); | ||
} | ||
envelope[i][j].setADSR(random(.001, myMaxAttack), random(.01, maxDecay)); // turning sustain level to 0. makes an AD envelope | ||
osc[i][j].amp(0.); | ||
oscVols[i][j] = random(.01, .3); | ||
if (idealOrReal == 0) | ||
{ | ||
var myOvertone = harmonicsArray[j]; | ||
} | ||
else | ||
{ | ||
var myOvertone = idealArray[j]; | ||
} | ||
osc[i][j].freq(freqValue * harmonicsArray[j] * random(1.0 - pitchDeviation, 1 + pitchDeviation) * pitchRatio); | ||
osc[i][j].start(); | ||
osc[i][j].disconnect(); | ||
//put 'em through that reverb, ahhhhhh yeah it's like a New Age in here | ||
cVerb.process(osc[i][j]); | ||
} | ||
} | ||
myPhraseAttack = new p5.Phrase('testerAttack', makeSoundAttack, atPattern); | ||
myPart = new p5.Part(); | ||
myPart.addPhrase(myPhraseAttack); | ||
myPart.setBPM(15); // super slow because it's in 16th notes | ||
myPart.loop(); | ||
myPart.start(); | ||
fft = new p5.FFT(); // for the drawing of the waveform (just using the buffer part) | ||
endPoint = width / numWaveforms; // for the drawing | ||
background(20); | ||
} | ||
|
||
function draw() | ||
{ | ||
background(0, 0, 0, 9); //to make the trails fade like on a scope :) | ||
var waveform = fft.waveform(); // analyze the waveform | ||
fft.analyze(); | ||
beginShape(); | ||
noFill(); | ||
stroke(fft.getEnergy("bass") * 2.0, fft.getEnergy("mid")* 2.0, fft.getEnergy("treble") * 2.0); // the (* 2.0) is just to make the colors a little brighter | ||
for (var i = 0; i < waveform.length; i++) | ||
{ | ||
var x = map(i, 0, waveform.length, startPoint, endPoint); | ||
var y = map(waveform[i], -.9, .9, height, 0); | ||
vertex(x, y); | ||
} | ||
endShape(); | ||
startPoint = endPoint + 1; | ||
endPoint += (width / numWaveforms); | ||
if (endPoint > width) | ||
{ | ||
redrawWaveform(); | ||
} | ||
} | ||
|
||
function makeSoundAttack(time, playbackRate) | ||
{ | ||
var whichNote = patternArray[note]; | ||
for (var i = 0; i < numOsc; i++) | ||
{ | ||
envelope[whichNote][i].ramp(osc[whichNote][i], time, (oscVols[whichNote][i] * random(.8, 1.0)), 0); // the added randomness just makes each strike a little different. | ||
} | ||
note = (note + 1) % patternArray.length; | ||
if (firstNote == 1) | ||
{ | ||
setTimeout(redrawWaveform, time * 1000.0); // just so the drawing display starts at the left on the first note | ||
} | ||
firstNote = 0; | ||
} | ||
|
||
|
||
function redrawWaveform() | ||
{ | ||
startPoint = 0; | ||
endPoint = (width / numWaveforms); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<!doctype html> | ||
<head> | ||
<script language="javascript" type="text/javascript" src="../../lib/p5.js"></script> | ||
|
||
<script language="javascript" type="text/javascript" src="../../lib/addons/p5.dom.js"></script> | ||
|
||
<script language="javascript" type="text/javascript" src="../../lib/p5.sound.js"></script> | ||
|
||
<script language="javascript" type="text/javascript" src="sketch.js"></script> | ||
|
||
</head> | ||
|
||
<body> | ||
click to trigger amplitude and frequency envelopes | ||
|
||
</body> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/** | ||
* Control the level of an envelope | ||
*/ | ||
|
||
var env; // this is the env | ||
var osc; // this oscillator will modulate the amplitude of the carrier | ||
var freqEnv; // env for frequency | ||
|
||
function setup() { | ||
env = new p5.Env(); | ||
env.setADSR(0.01, 0.2, 0.2, 0.3); | ||
env.setRange(0, 1); | ||
|
||
freqEnv = new p5.Env(); | ||
freqEnv.setADSR(0.01, 0.2, 0.2, 0.3); | ||
freqEnv.setRange(300, 5000); | ||
|
||
|
||
osc = new p5.Oscillator(); // connects to master output by default | ||
osc.start(0); | ||
osc.freq(220); | ||
// osc.freq(env.scale(0,1,800,300)); | ||
osc.freq(freqEnv); | ||
osc.amp(env); | ||
} | ||
|
||
function mousePressed() { | ||
env.triggerAttack(); | ||
freqEnv.triggerAttack(); | ||
} | ||
|
||
function mouseReleased() { | ||
env.triggerRelease(); | ||
freqEnv.triggerRelease(); | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
/** | ||
* @name Note Envelope | ||
* @description <p>An Envelope is a series of fades, defined | ||
* as time / value pairs. In this example, the envelope | ||
* will be used to "play" a note by controlling the output | ||
* amplitude of an oscillator.<br/><br/> | ||
* The p5.Oscillator sends its output through | ||
* an internal Web Audio GainNode (p5.Oscillator.output). | ||
* By default, that node has a constant value of 0.5. It can | ||
* be reset with the osc.amp() method. Or, in this example, an | ||
* Envelope takes control of that node, turning the amplitude | ||
* up and down like a volume knob.</p> | ||
* <p><em><span class="small"> To run this example locally, you will need the | ||
* <a href="http://p5js.org/reference/#/libraries/p5.sound">p5.sound library</a> and a | ||
* sound file.</span></em></p> | ||
*/ | ||
var osc, envelope, fft; | ||
var myPhraseAttack, myPhraseRelease, myPart; | ||
var atPattern = [1, 0]; | ||
var relPattern = [0, 1]; | ||
var scaleArray = [60, 62, 64, 65, 67, 69, 71, 72]; | ||
var note = 0; | ||
var expOrNot = 1; | ||
var startPoint = 0; | ||
var endPoint = 0; | ||
var numWaveforms = 50; | ||
|
||
var audioContext; | ||
|
||
function setup() { | ||
createCanvas(710, 200); | ||
osc = new p5.SinOsc(); | ||
|
||
audioContext = getAudioContext(); | ||
|
||
// Instantiate the envelope with time / value pairs | ||
envelope = new p5.Env(0.1, 0.5, 0.01, 0.0, 0.0, 0.0, 0.0, 0.0); | ||
osc.amp(0.); | ||
osc.start(); | ||
myPhraseAttack = new p5.Phrase('testerAttack', makeSoundAttack, atPattern); | ||
myPhraseRelease = new p5.Phrase('testerRelease', makeSoundRelease, relPattern); | ||
myPart = new p5.Part(); | ||
myPart.addPhrase(myPhraseAttack); | ||
//myPart.addPhrase(myPhraseRelease); | ||
myPart.setBPM(120); | ||
myPart.loop(); | ||
myPart.start(); | ||
fft = new p5.FFT(); | ||
fft.setInput(osc); | ||
masterVolume(0); | ||
endPoint = width / numWaveforms; | ||
noStroke(); | ||
background(20); | ||
} | ||
|
||
function draw() { | ||
|
||
var waveform = fft.waveform(); // analyze the waveform | ||
beginShape(); | ||
strokeWeight(5); | ||
for (var i = 0; i < waveform.length; i++){ | ||
var x = map(i, 0, waveform.length, startPoint, endPoint); | ||
var y = map(waveform[i], -1, 1, height, 0); | ||
vertex(x, y); | ||
} | ||
endShape(); | ||
startPoint = endPoint + 1; | ||
endPoint += (width / numWaveforms); | ||
if (endPoint > width) | ||
{ | ||
background(20); | ||
startPoint = 0; | ||
endPoint = (width / numWaveforms); | ||
} | ||
|
||
|
||
} | ||
|
||
|
||
function makeSoundAttack(time, playbackRate) | ||
{ | ||
var midiValue = scaleArray[note]; | ||
var freqValue = midiToFreq(midiValue); | ||
|
||
if (note == 0) | ||
{ | ||
// if (expOrNot == 0) | ||
// { | ||
// envelope.setExp(true); | ||
// expOrNot = 1; | ||
// } | ||
// else | ||
// { | ||
// envelope.setExp(false); | ||
// expOrNot = 0; | ||
// } | ||
} | ||
|
||
osc.freq(freqValue * 2, 0, time); | ||
// envelope.play(osc, time); | ||
envelope.triggerAttack(osc, time); | ||
//envelope.triggerRelease(osc); | ||
note = (note + 1) % scaleArray.length; | ||
setTimeout(redrawWaveform, time * 1000.0); | ||
|
||
} | ||
|
||
function makeSoundRelease(time, playbackRate) | ||
{ | ||
envelope.triggerRelease(osc, time); | ||
} | ||
|
||
function redrawWaveform() | ||
{ | ||
background(20); | ||
startPoint = 0; | ||
endPoint = (width / numWaveforms); | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.