week4-html-files.zip
-- all the html/javascript files we created in class (covered
below, not all full listings this time).
Here is a tour through the class work:
We looked again at the very basic Tone.js oscillator and the various
waveforms it can use. I also wanted to cover the different (but
operationally identical) ways of doing things with Tone.js, specifically
the initialization of Tone.js elements. Here is the html that did
this:
<!DOCTYPE HTML>
<html>
<head>
<title>oscwaves2</title>
<script src="../Tone.js"></script>
</head>
<body>
<button onclick="startbuttonfunction()">start me up!</button>
<br>
<br>
<button onclick="stopbuttonfunction()">STOPIT!</button>
<script>
// three different ways of setting up an oscillator
// 1:
var osc = new Tone.Oscillator(378, "square").toMaster();
/*
// 2:
var osc;
osc = new Tone.Oscillator();
osc.frequency.value = 378.0;
osc.type = "square";
osc.toMaster();
// 3:
var osc = new Tone.Oscillator( {
type: "square",
frequency: 378
} );
osc.toMaster();
*/
function startbuttonfunction() {
osc.start();
}
function startbuttonfunction() {
osc.start();
}
function stopbuttonfunction() {
osc.stop();
}
</script>
</body>
</html>
click here to run the above code
note the different 'comment' styles in the above code. Comment and
uncomment different parts for different initialization approaches.
Next we looked at some of the other oscillators available in Tone.js.
We used the defaults from the Tone.js documentation:
<!DOCTYPE HTML>
<html>
<head>
<title>various_oscs</title>
<script src="../Tone.js"></script>
</head>
<body>
<button onclick="startbuttonfunction()">make sound</button>
<br>
<br>
<button onclick="stopbuttonfunction()">enough aready</button>
<br>
<br>
<script>
var theosc = new Tone.PWMOscillator("Ab3", 0.3).toMaster();
// note error in docs for FatOscillator
// var theosc = new Tone.FatOscillator("Ab3", "square").toMaster();
// var theosc = new Tone.PulseOscillator("E5", 0.4).toMaster();
function startbuttonfunction() {
theosc.start();
}
function stopbuttonfunction() {
theosc.stop();
}
</script>
</body>
</html>
click here to run the above code
We revisited the
fmosc1.html FM oscillator we coded in
last week's class, and then we added an envelope to the modulationIndex
so that we could trigger an "FM sweep" sound:
<!DOCTYPE HTML>
<html>
<head>
<title>fmosc2</title>
<script src="../Tone.js"></script>
</head>
<body>
<button onclick="startbuttonfunction()">ho ho!</button>
<br>
<br>
<button onclick="stopbuttonfunction()">ha ha!</button>
<br>
<br>
<input type="range" oninput="set_harmonicity(this.value)" min="1" max="50">
<output id="output1"></output>
<br>
<br>
<br>
<br>
<!-- this will trigger an envelope on the FM index -->
<button onclick="GObuttonfunction()">gogogogo</button>
<script>
var fmosc = new Tone.FMOscillator ( {
frequency : 314,
modulationType : "sine",
harmonicity : 1,
} );
fmosc.toMaster();
// attack of 0.1 secs, sustain at full volume (1.0), release of 0.3 secs
var dexenv = new Tone.ScaledEnvelope(0.1, 0.0, 1.0, 0.3);
dexenv.min = 0;
dexenv.max = 1000; // this is very weird. a bug in Tone.js? should be 10
dexenv.connect(fmosc.modulationIndex);
function startbuttonfunction() {
fmosc.start();
}
function stopbuttonfunction() {
fmosc.stop();
}
function set_harmonicity(val) {
// again,this is so we get a larger range of values in our range slider
document.getElementById('output1').innerHTML = val/10;
fmosc.harmonicity.value = val/10;
}
function GObuttonfunction() {
// 0.5 is the duration of the sustain for this note
dexenv.triggerAttackRelease(0.5);
}
</script>
</body>
</html>
click here to run the above code
Many of these enveloping additions are so common that Tone.js
has a set of pre-built "synths" with that capability included.
We explored a number of them using the following html (again relying
on the defaults from the Tone.js docs):
<!DOCTYPE HTML>
<html>
<head>
<title>various_synths</title>
<script src="../Tone.js"></script>
</head>
<body>
<button onclick="startbuttonfunction()">bleep</button>
<script>
var theSynth = new Tone.FMSynth().toMaster();
// var theSynth = new Tone.AMSynth().toMaster();
// var theSynth = new Tone.DuoSynth().toMaster();
// var theSynth = new Tone.PluckSynth().toMaster();
// var theSynth = new Tone.MembraneSynth().toMaster();
// note: take out pitch in the triggerAttackRelease() for the MetalSynth
// var theSynth = new Tone.MetalSynth().toMaster();
function startbuttonfunction() {
theSynth.triggerAttackRelease("C4", 0.1);
}
</script>
</body>
</html>
click here to run the above code
We then moved to signal-processing, starting by making noise:
<!DOCTYPE HTML>
<html>
<head>
<title>noise</title>
<script src="../Tone.js"></script>
</head>
<body>
<button onclick="startbuttonfunction()">noisey</button>
<br>
<br>
<button onclick="stopbuttonfunction()">noiseless</button>
<br>
<br>
<script>
var noise = new Tone.Noise();
noise.toMaster();
function startbuttonfunction() {
noise.start();
}
function stopbuttonfunction() {
noise.stop();
}
</script>
</body>
</html>
click here to run the above code
We added a bandpass filter following the noise generator:
<!DOCTYPE HTML>
<html>
<head>
<title>noisefilt1</title>
<script src="../Tone.js"></script>
</head>
<body>
<button onclick="startbuttonfunction()">noisey</button>
<br>
<br>
<button onclick="stopbuttonfunction()">noiseless</button>
<br>
<br>
<script>
var noise = new Tone.Noise();
var filt = new Tone.Filter( {
type: "bandpass",
frequency: 350,
rolloff: -24,
Q: 4
} );
noise.connect(filt);
filt.toMaster();
function startbuttonfunction() {
noise.start();
}
function stopbuttonfunction() {
noise.stop();
}
</script>
</body>
</html>
click here to run the above code
The filter decreased the amplitude of the sound, so we put in a
Tone.Volume element to boost the output. Here are the relevant lines in
the code:
var volume = new Tone.Volume();
volume.volume.value = 20.0; // could have set this in the initialization
// noise -> filt -> volume -> toMaster
noise.connect(filt);
filt.connect(volume);
volume.toMaster();
click here to run the code with the volume
slider included
We also added a slider for the center frequency of the bandpass filter,
click here to run that code
and ultimately we added an envelope to sweep the center frequency with
a button trigger:
<!DOCTYPE HTML>
<html>
<head>
<title>noisefilt3</title>
<script src="../Tone.js"></script>
</head>
<body>
<button onclick="startbuttonfunction()">noisey</button>
<br>
<br>
<button onclick="stopbuttonfunction()">noiseless</button>
<br>
<br>
<br>
<!-- this will now set the upper limit of the envelope sweep -->
<i>set the upper frequency for the filter sweep:</i>
<br>
<input type="range" oninput="set_upperfreq(this.value)">
<output id="output"></output>
<br>
<br>
<!-- set the range on the slider itself -->
<input type="range" oninput="set_vol(this.value)" min="0" max="20">
<output id="output1"></output>
<br>
<br>
<br>
<i>click this button to trigger the emvelope:</i>
<button onclick="filtenvfunction()">sweep...</button>
<script>
var noise = new Tone.Noise();
var filt = new Tone.Filter( {
type: "bandpass",
frequency: 350,
rolloff: -24,
Q: 4
} );
var volume = new Tone.Volume();
volume.volume.value = 20.0; // could have set this in the initialization
var upperfreq;
var freqenv = new Tone.ScaledEnvelope(2.0, 0.0, 1.0, 5.0);
freqenv.min = 10; // setting it to 0 made a thump
freqenv.connect(filt.frequency); // control the frequency of the filter
// noise -> filt -> volume -> toMaster
noise.connect(filt);
filt.connect(volume);
volume.toMaster();
function startbuttonfunction() {
noise.start();
}
function stopbuttonfunction() {
noise.stop();
}
function set_upperfreq(fval) {
var actualval = fval * 20; // range 0 -- 2000 (1-100 on the slider)
upperfreq = actualval;
document.getElementById('output').innerHTML = actualval;
}
function set_vol(vval) {
volume.volume.value = vval;
document.getElementById('output1').innerHTML = vval;
}
function filtenvfunction() {
freqenv.max = upperfreq; // from the slider
freqenv.triggerAttackRelease(2.5);
}
</script>
</body>
</html>
click here to run the code with the volume
slider included
Then we added echo!
and reverb!
and chorusing!
NOTE: use the "view source" capability of your browser to see the
code for these variations on the basic noise/filter instrument, or download
the archive at the top of this section -- all of the html pages are included
in it.
The last thing we did was to work up a small 'piece' using pitched
comb filters and continuous and impulsive noise. The piece was
'performed' by hitting two buttons on the web page. The development
of the code is tracked by these files (click on each one to run it
or view the source):
Assignment
+ make some Tone.js sound!